term 查询
精确值查询
查询 price 字段等于6000的文档
# 新增三个文档
PUT /ad/_doc/1
{
"name":"phone 8",
"price":6000,
"color":"white",
"ad":"this is a white phone",
"label":[
"white",
"nice"
]
}
PUT /ad/_doc/2
{
"name":"xiaomi 8",
"price":4000,
"color":"red",
"ad":"this is a red phone",
"label":[
"white",
"xiaomi"
]
}
PUT /ad/_doc/3
{
"name":"huawei p30",
"price":5000,
"color":"white",
"ad":"this is a white phone",
"label":[
"white",
"huawei"
]
}
查询price字段等于6000的文档
GET /ad/_search
{
"query":{
"term":{
"price":{
"value":"6000"
}
}
}
}
# 输出结果
{
"took":0,
"timed_out":false,
"_shards":{
"total":1,
"successful":1,
"skipped":0,
"failed":0
},
"hits":{
"total":{
"value":1,
"relation":"eq"
},
"max_score":1,
"hits":[
{
"_index":"ad",
"_type":"_doc",
"_id":"1",
"_score":1,
"_source":{
"name":"phone 8",
"price":6000,
"color":"white",
"ad":"this is a white phone",
"label":[
"white",
"nice"
]
}
}
]
}
}
查询 name 字段等于 phone 8 的文档
GET /ad/_search
{
"query":{
"term":{
"name":{
"value":"phone 8"
}
}
}
}
# 输出结果
{
"took":0,
"timed_out":false,
"_shards":{
"total":1,
"successful":1,
"skipped":0,
"failed":0
},
"hits":{
"total":{
"value":0,
"relation":"eq"
},
"max_score":null,
"hits":[
]
}
}
默认情况下,Elasticsearch 针对 text 字段的值进行解析分词,这会使查找 text 字段值的精确匹配变得困难。要搜索 text 字段值,需改用 match 查询。
为什么没有查到 phone 8 的这个文档呢,这里需要介绍一下 term 的查询原理:
term 查询会去倒排索引中寻找确切的 term ,它并不会走分词器,只会去匹配倒排索引 ,而 name 字段的type 类型是 text ,会进行分词,将 phone 8 分为 phone 和 8 ,我们使用 term 查询 phone 8 时倒排索引中没有 phone 8 ,所以没有查询到匹配的文档。
term 查询与 match 查询的区别:
- term 查询时,不会分词,直接匹配倒排索引。
- match 查询时会进行分词,查询 phone 8 时,会先分词成 phone 和 8 ,然后去匹配倒排索引,所以结果会将 phone 8 和 xiaomi 8 两个文档都查出来。
还有一点需要注意,因为 term 查询不会走分词器,但是会去匹配倒排索引,所以查询的结构就跟分词器如何分词有关系,比如新增一个 /ad 的文档, name 字段赋值为 Oppo ,这时使用 term 查询 Oppo 不会查询出文档,这时因为es默认是用的 standard 分词器,它在分词后会将单词转成小写输出,所以使用 Oppo 查不出文档,使用小写 oppo 可以查出来。
# 新增文档
PUT /ad/_doc/4
{
"name":"Oppo",
"price":3999,
"color":"white",
"ad":"this is a white phone",
"label":[
"white",
"Oppo"
]
}
# 使用Oppo查询不出文档,改成oppo可以查出新添加的文档
GET /ad/_search
{
"query":{
"term":{
"name":{
"value":"Oppo"
}
}
}
}
这里说的并不是想让你了解 standard 分词器,而是要get到所有像 term 这类的查询结果跟选择的分词器有关系,了解选择的分词器分词方式有助于我们编写查询语句。