|
1 | 1 | [[query-dsl-term-query]]
|
2 | 2 | === Term Query
|
3 | 3 |
|
4 |
| -The `term` query finds documents that contain the *exact* term specified |
5 |
| -in the inverted index. For instance: |
| 4 | +Returns documents that contain an *exact* term in a provided field. |
6 | 5 |
|
7 |
| -[source,js] |
8 |
| --------------------------------------------------- |
9 |
| -POST _search |
10 |
| -{ |
11 |
| - "query": { |
12 |
| - "term" : { "user" : "Kimchy" } <1> |
13 |
| - } |
14 |
| -} |
15 |
| --------------------------------------------------- |
16 |
| -// CONSOLE |
17 |
| -<1> Finds documents which contain the exact term `Kimchy` in the inverted index |
18 |
| - of the `user` field. |
| 6 | +You can use the `term` query to find documents based on a precise value such as |
| 7 | +a price, a product ID, or a username. |
| 8 | + |
| 9 | +[WARNING] |
| 10 | +==== |
| 11 | +Avoid using the `term` query for <<text, `text`>> fields. |
| 12 | +
|
| 13 | +By default, {es} changes the values of `text` fields as part of <<analysis, |
| 14 | +analysis>>. This can make finding exact matches for `text` field values |
| 15 | +difficult. |
19 | 16 |
|
20 |
| -A `boost` parameter can be specified to give this `term` query a higher |
21 |
| -relevance score than another query, for instance: |
| 17 | +To search `text` field values, use the <<query-dsl-match-query,`match`>> query |
| 18 | +instead. |
| 19 | +==== |
| 20 | + |
| 21 | +[[term-query-ex-request]] |
| 22 | +==== Example request |
22 | 23 |
|
23 | 24 | [source,js]
|
24 |
| --------------------------------------------------- |
25 |
| -GET _search |
| 25 | +---- |
| 26 | +GET /_search |
26 | 27 | {
|
27 |
| - "query": { |
28 |
| - "bool": { |
29 |
| - "should": [ |
30 |
| - { |
31 |
| - "term": { |
32 |
| - "status": { |
33 |
| - "value": "urgent", |
34 |
| - "boost": 2.0 <1> |
| 28 | + "query": { |
| 29 | + "term": { |
| 30 | + "user": { |
| 31 | + "value": "Kimchy", |
| 32 | + "boost": 1.0 |
35 | 33 | }
|
36 |
| - } |
37 |
| - }, |
38 |
| - { |
39 |
| - "term": { |
40 |
| - "status": "normal" <2> |
41 |
| - } |
42 | 34 | }
|
43 |
| - ] |
44 | 35 | }
|
45 |
| - } |
46 | 36 | }
|
47 |
| --------------------------------------------------- |
| 37 | +---- |
48 | 38 | // CONSOLE
|
49 | 39 |
|
50 |
| -<1> The `urgent` query clause has a boost of `2.0`, meaning it is twice as important |
51 |
| - as the query clause for `normal`. |
52 |
| -<2> The `normal` clause has the default neutral boost of `1.0`. |
53 |
| - |
54 |
| -A `term` query can also match against <<range, range data types>>. |
55 |
| - |
56 |
| -.Why doesn't the `term` query match my document? |
57 |
| -************************************************** |
58 |
| -
|
59 |
| -String fields can be of type `text` (treated as full text, like the body of an |
60 |
| -email), or `keyword` (treated as exact values, like an email address or a |
61 |
| -zip code). Exact values (like numbers, dates, and keywords) have |
62 |
| -the exact value specified in the field added to the inverted index in order |
63 |
| -to make them searchable. |
64 |
| -
|
65 |
| -However, `text` fields are `analyzed`. This means that their |
66 |
| -values are first passed through an <<analysis,analyzer>> to produce a list of |
67 |
| -terms, which are then added to the inverted index. |
68 |
| -
|
69 |
| -There are many ways to analyze text: the default |
70 |
| -<<analysis-standard-analyzer,`standard` analyzer>> drops most punctuation, |
71 |
| -breaks up text into individual words, and lower cases them. For instance, |
72 |
| -the `standard` analyzer would turn the string ``Quick Brown Fox!'' into the |
73 |
| -terms [`quick`, `brown`, `fox`]. |
74 |
| -
|
75 |
| -This analysis process makes it possible to search for individual words |
76 |
| -within a big block of full text. |
77 |
| -
|
78 |
| -The `term` query looks for the *exact* term in the field's inverted index -- |
79 |
| -it doesn't know anything about the field's analyzer. This makes it useful for |
80 |
| -looking up values in keyword fields, or in numeric or date |
81 |
| -fields. When querying full text fields, use the |
82 |
| -<<query-dsl-match-query,`match` query>> instead, which understands how the field |
83 |
| -has been analyzed. |
84 |
| -
|
85 |
| -
|
86 |
| -To demonstrate, try out the example below. First, create an index, specifying the field mappings, and index a document: |
| 40 | +[[term-top-level-params]] |
| 41 | +==== Top-level parameters for `term` |
| 42 | +`<field>`:: |
| 43 | +Field you wish to search. |
| 44 | + |
| 45 | +[[term-field-params]] |
| 46 | +==== Parameters for `<field>` |
| 47 | +`value`:: |
| 48 | +Term you wish to find in the provided `<field>`. To return a document, the term |
| 49 | +must exactly match the field value, including whitespace and capitalization. |
| 50 | + |
| 51 | +`boost`:: |
| 52 | +Floating point number used to decrease or increase the |
| 53 | +<<query-filter-context, relevance scores>> of a query. Default is `1.0`. |
| 54 | +Optional. |
| 55 | ++ |
| 56 | +You can use the `boost` parameter to adjust relevance scores for searches |
| 57 | +containing two or more queries. |
| 58 | ++ |
| 59 | +Boost values are relative to the default value of `1.0`. A boost value between |
| 60 | +`0` and `1.0` decreases the relevance score. A value greater than `1.0` |
| 61 | +increases the relevance score. |
| 62 | + |
| 63 | +[[term-query-notes]] |
| 64 | +==== Notes |
| 65 | + |
| 66 | +[[avoid-term-query-text-fields]] |
| 67 | +===== Avoid using the `term` query for `text` fields |
| 68 | +By default, {es} changes the values of `text` fields during analysis. For |
| 69 | +example, the default <<analysis-standard-analyzer, standard analyzer>> changes |
| 70 | +`text` field values as follows: |
| 71 | + |
| 72 | +* Removes most punctuation |
| 73 | +* Divides the remaining content into individual words, called |
| 74 | +<<analysis-tokenizers, tokens>> |
| 75 | +* Lowercases the tokens |
| 76 | + |
| 77 | +To better search `text` fields, the `match` query also analyzes your provided |
| 78 | +search term before performing a search. This means the `match` query can search |
| 79 | +`text` fields for analyzed tokens rather than an exact term. |
| 80 | + |
| 81 | +The `term` query does *not* analyze the search term. The `term` query only |
| 82 | +searches for the *exact* term you provide. This means the `term` query may |
| 83 | +return poor or no results when searching `text` fields. |
| 84 | + |
| 85 | +To see the difference in search results, try the following example. |
| 86 | + |
| 87 | +. Create an index with a `text` field called `full_text`. |
| 88 | ++ |
| 89 | +-- |
87 | 90 |
|
88 | 91 | [source,js]
|
89 |
| --------------------------------------------------- |
| 92 | +---- |
90 | 93 | PUT my_index
|
91 | 94 | {
|
92 |
| - "mappings": { |
93 |
| - "_doc": { |
94 |
| - "properties": { |
95 |
| - "full_text": { |
96 |
| - "type": "text" <1> |
97 |
| - }, |
98 |
| - "exact_value": { |
99 |
| - "type": "keyword" <2> |
| 95 | + "mappings" : { |
| 96 | + "properties" : { |
| 97 | + "full_text" : { "type" : "text" } |
100 | 98 | }
|
101 |
| - } |
102 | 99 | }
|
103 |
| - } |
104 | 100 | }
|
| 101 | +---- |
| 102 | +// CONSOLE |
| 103 | + |
| 104 | +-- |
105 | 105 |
|
| 106 | +. Index a document with a value of `Quick Brown Foxes!` in the `full_text` |
| 107 | +field. |
| 108 | ++ |
| 109 | +-- |
| 110 | + |
| 111 | +[source,js] |
| 112 | +---- |
106 | 113 | PUT my_index/_doc/1
|
107 | 114 | {
|
108 |
| - "full_text": "Quick Foxes!", <3> |
109 |
| - "exact_value": "Quick Foxes!" <4> |
| 115 | + "full_text": "Quick Brown Foxes!" |
110 | 116 | }
|
111 |
| --------------------------------------------------- |
| 117 | +---- |
112 | 118 | // CONSOLE
|
| 119 | +// TEST[continued] |
| 120 | + |
| 121 | +Because `full_text` is a `text` field, {es} changes `Quick Brown Foxes!` to |
| 122 | +`[quick, brown, fox]` during analysis. |
113 | 123 |
|
114 |
| -<1> The `full_text` field is of type `text` and will be analyzed. |
115 |
| -<2> The `exact_value` field is of type `keyword` and will NOT be analyzed. |
116 |
| -<3> The `full_text` inverted index will contain the terms: [`quick`, `foxes`]. |
117 |
| -<4> The `exact_value` inverted index will contain the exact term: [`Quick Foxes!`]. |
| 124 | +-- |
118 | 125 |
|
119 |
| -Now, compare the results for the `term` query and the `match` query: |
| 126 | +. Use the `term` query to search for `Quick Brown Foxes!` in the `full_text` |
| 127 | +field. Include the `pretty` parameter so the response is more readable. |
| 128 | ++ |
| 129 | +-- |
120 | 130 |
|
121 | 131 | [source,js]
|
122 |
| --------------------------------------------------- |
123 |
| -GET my_index/_search |
| 132 | +---- |
| 133 | +GET my_index/_search?pretty |
124 | 134 | {
|
125 | 135 | "query": {
|
126 | 136 | "term": {
|
127 |
| - "exact_value": "Quick Foxes!" <1> |
| 137 | + "full_text": "Quick Brown Foxes!" |
128 | 138 | }
|
129 | 139 | }
|
130 | 140 | }
|
| 141 | +---- |
| 142 | +// CONSOLE |
| 143 | +// TEST[continued] |
131 | 144 |
|
132 |
| -GET my_index/_search |
133 |
| -{ |
134 |
| - "query": { |
135 |
| - "term": { |
136 |
| - "full_text": "Quick Foxes!" <2> |
137 |
| - } |
138 |
| - } |
139 |
| -} |
| 145 | +Because the `full_text` field no longer contains the *exact* term `Quick Brown |
| 146 | +Foxes!`, the `term` query search returns no results. |
140 | 147 |
|
141 |
| -GET my_index/_search |
142 |
| -{ |
143 |
| - "query": { |
144 |
| - "term": { |
145 |
| - "full_text": "foxes" <3> |
146 |
| - } |
147 |
| - } |
148 |
| -} |
| 148 | +-- |
| 149 | + |
| 150 | +. Use the `match` query to search for `Quick Brown Foxes!` in the `full_text` |
| 151 | +field. |
| 152 | ++ |
| 153 | +-- |
| 154 | + |
| 155 | +//// |
149 | 156 |
|
150 |
| -GET my_index/_search |
| 157 | +[source,js] |
| 158 | +---- |
| 159 | +POST my_index/_refresh |
| 160 | +---- |
| 161 | +// CONSOLE |
| 162 | +// TEST[continued] |
| 163 | +
|
| 164 | +//// |
| 165 | + |
| 166 | +[source,js] |
| 167 | +---- |
| 168 | +GET my_index/_search?pretty |
151 | 169 | {
|
152 | 170 | "query": {
|
153 | 171 | "match": {
|
154 |
| - "full_text": "Quick Foxes!" <4> |
| 172 | + "full_text": "Quick Brown Foxes!" |
155 | 173 | }
|
156 | 174 | }
|
157 | 175 | }
|
158 |
| --------------------------------------------------- |
| 176 | +---- |
159 | 177 | // CONSOLE
|
160 | 178 | // TEST[continued]
|
161 | 179 |
|
162 |
| -<1> This query matches because the `exact_value` field contains the exact |
163 |
| - term `Quick Foxes!`. |
164 |
| -<2> This query does not match, because the `full_text` field only contains |
165 |
| - the terms `quick` and `foxes`. It does not contain the exact term |
166 |
| - `Quick Foxes!`. |
167 |
| -<3> A `term` query for the term `foxes` matches the `full_text` field. |
168 |
| -<4> This `match` query on the `full_text` field first analyzes the query string, |
169 |
| - then looks for documents containing `quick` or `foxes` or both. |
170 |
| -************************************************** |
| 180 | +Unlike the `term` query, the `match` query analyzes your provided search term, |
| 181 | +`Quick Brown Foxes!`, before performing a search. The `match` query then returns |
| 182 | +any documents containing the `quick`, `brown`, or `fox` tokens in the |
| 183 | +`full_text` field. |
| 184 | + |
| 185 | +Here's the response for the `match` query search containing the indexed document |
| 186 | +in the results. |
| 187 | + |
| 188 | +[source,js] |
| 189 | +---- |
| 190 | +{ |
| 191 | + "took" : 1, |
| 192 | + "timed_out" : false, |
| 193 | + "_shards" : { |
| 194 | + "total" : 1, |
| 195 | + "successful" : 1, |
| 196 | + "skipped" : 0, |
| 197 | + "failed" : 0 |
| 198 | + }, |
| 199 | + "hits" : { |
| 200 | + "total" : { |
| 201 | + "value" : 1, |
| 202 | + "relation" : "eq" |
| 203 | + }, |
| 204 | + "max_score" : 0.8630463, |
| 205 | + "hits" : [ |
| 206 | + { |
| 207 | + "_index" : "my_index", |
| 208 | + "_type" : "_doc", |
| 209 | + "_id" : "1", |
| 210 | + "_score" : 0.8630463, |
| 211 | + "_source" : { |
| 212 | + "full_text" : "Quick Brown Foxes!" |
| 213 | + } |
| 214 | + } |
| 215 | + ] |
| 216 | + } |
| 217 | +} |
| 218 | +---- |
| 219 | +// TESTRESPONSE[s/"took" : 1/"took" : $body.took/] |
| 220 | +-- |
0 commit comments