Skip to content

Commit a6ccd68

Browse files
Docs: Rewrote the term query docs to explain analyzed vs not_analyzed
1 parent c89c116 commit a6ccd68

File tree

1 file changed

+146
-11
lines changed

1 file changed

+146
-11
lines changed
Lines changed: 146 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,166 @@
11
[[query-dsl-term-query]]
22
=== Term Query
33

4-
Matches documents that have fields that contain a term (*not analyzed*).
5-
The term query maps to Lucene `TermQuery`. The following matches
6-
documents where the user field contains the term `kimchy`:
4+
The `term` query finds documents that contain the *exact* term specified
5+
in the inverted index. For instance:
76

87
[source,js]
98
--------------------------------------------------
109
{
11-
"term" : { "user" : "kimchy" }
12-
}
10+
"term" : { "user" : "Kimchy" } <1>
11+
}
1312
--------------------------------------------------
13+
<1> Finds documents which contain the exact term `Kimchy` in the inverted index
14+
of the `user` field.
1415

15-
A boost can also be associated with the query:
16+
A `boost` parameter can be specified to give this `term` query a higher
17+
relevance score than another query, for instance:
1618

1719
[source,js]
1820
--------------------------------------------------
21+
GET /_search
1922
{
20-
"term" : { "user" : { "value" : "kimchy", "boost" : 2.0 } }
21-
}
23+
"query": {
24+
"bool": {
25+
"should": [
26+
{
27+
"term": {
28+
"status": {
29+
"value": "urgent",
30+
"boost": 2.0 <1>
31+
}
32+
}
33+
},
34+
{
35+
"term": {
36+
"status": "normal" <2>
37+
}
38+
}
39+
]
40+
}
41+
}
42+
}
2243
--------------------------------------------------
2344

24-
Or :
45+
<1> The `urgent` query clause has a boost of `2.0`, meaning it is twice as important
46+
as the query clause for `normal`.
47+
<2> The `normal` clause has the default neutral boost of `1.0`.
48+
49+
.Why doesn't the `term` query match my document?
50+
**************************************************
51+
52+
String fields can be `analyzed` (treated as full text, like the body of an
53+
email), or `not_analyzed` (treated as exact values, like an email address or a
54+
zip code). Exact values (like numbers, dates, and `not_analyzed` strings) have
55+
the exact value specified in the field added to the inverted index in order
56+
to make them searchable.
57+
58+
By default, however, `string` fields are `analyzed`. This means that their
59+
values are first passed through an <<analysis,analyzer>> to produce a list of
60+
terms, which are then added to the inverted index.
61+
62+
There are many ways to analyze text: the default
63+
<<analysis-standard-analyzer,`standard` analyzer>> drops most punctuation,
64+
breaks up text into individual words, and lower cases them. For instance,
65+
the `standard` analyzer would turn the string ``Quick Brown Fox!'' into the
66+
terms [`quick`, `brown`, `fox`].
67+
68+
This analysis process makes it possible to search for individual words
69+
within a big block of full text.
70+
71+
The `term` query looks for the *exact* term in the field's inverted index --
72+
it doesn't know anything about the field's analyzer. This makes it useful for
73+
looking up values in `not_analyzed` string fields, or in numeric or date
74+
fields. When querying full text fields, use the
75+
<<query-dsl-match-query,`match` query>> instead, which understands how the field
76+
has been analyzed.
77+
78+
79+
To demonstrate, try out the example below. First, create an index, specifying the field mappings, and index a document:
2580
2681
[source,js]
2782
--------------------------------------------------
83+
PUT my_index
84+
{
85+
"mappings": {
86+
"my_type": {
87+
"properties": {
88+
"full_text": {
89+
"type": "string" <1>
90+
},
91+
"exact_value": {
92+
"type": "string",
93+
"index": "not_analyzed" <2>
94+
}
95+
}
96+
}
97+
}
98+
}
99+
100+
PUT my_index/my_type/1
28101
{
29-
"term" : { "user" : { "term" : "kimchy", "boost" : 2.0 } }
30-
}
102+
"full_text": "Quick Foxes!", <3>
103+
"exact_value": "Quick Foxes!" <4>
104+
}
31105
--------------------------------------------------
106+
// AUTOSENSE
107+
108+
<1> The `full_text` field is `analyzed` by default.
109+
<2> The `exact_value` field is set to be `not_analyzed`.
110+
<3> The `full_text` inverted index will contain the terms: [`quick`, `foxes`].
111+
<4> The `exact_value` inverted index will contain the exact term: [`Quick Foxes!`].
112+
113+
Now, compare the results for the `term` query and the `match` query:
114+
115+
[source,js]
116+
--------------------------------------------------
117+
118+
GET my_index/my_type/_search
119+
{
120+
"query": {
121+
"term": {
122+
"exact_value": "Quick Foxes!" <1>
123+
}
124+
}
125+
}
126+
127+
GET my_index/my_type/_search
128+
{
129+
"query": {
130+
"term": {
131+
"full_text": "Quick Foxes!" <2>
132+
}
133+
}
134+
}
135+
136+
GET my_index/my_type/_search
137+
{
138+
"query": {
139+
"term": {
140+
"exact_value": "foxes" <3>
141+
}
142+
}
143+
}
144+
145+
GET my_index/my_type/_search
146+
{
147+
"query": {
148+
"match": {
149+
"full_text": "Quick Foxes!" <4>
150+
}
151+
}
152+
}
153+
--------------------------------------------------
154+
// AUTOSENSE
155+
156+
<1> This query matches because the `exact_value` field contains the exact
157+
term `Quick Foxes!`.
158+
<2> This query does not match, because the `full_text` field only contains
159+
the terms `quick` and `foxes`. It does not contain the exact term
160+
`Quick Foxes!`.
161+
<3> A `term` query for the term `foxes` matches the `full_text` field.
162+
<4> This `match` query on the `full_text` field first analyzes the query string,
163+
then looks for documents containing `quick` or `foxes` or both.
164+
**************************************************
165+
166+

0 commit comments

Comments
 (0)