在ES中,bool查询存在着一些比较坑的点需要注意:
基础知识点
布尔查询是最常用的组合查询,根据子查询的规则,只有当文档满足所有子查询条件时(即bool查询中的所有子查询的最后需要作and),elasticsearch引擎才将结果返回。布尔查询支持的子查询条件共4种:
- must(and)返回的文档必须满足must中所有子句的条件,并且参与计算分值
# 查询文档中desc精确匹配“中国人”,
# 而且desc必须能够到
# 匹配“哈哈嘻嘻呼呼方面中国传统”的文档。
# (match会对关键词进行分词,有满足的即返回)
GET /dangdang/books/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"desc": {
"value": "中国人"
}
}
},
{
"match": {
"desc": "哈哈嘻嘻呼呼方面中国传统"
}
}
]
}
}
}
- should(or)返回的文档可能满足should子句的条件,在一个bool查询中,如果没有must或者filter,当should有一个或多个条件时,默认那么只要满足一个就可以返回。
# 查询文档中desc包含了“中国人”
# 或者包含了“引用”的文档
GET /dangdang/books/_search
{
"query": {
"bool": {
"should": [
{
"term": {
"desc": {
"value": "中国人"
}
}
},
{
"term": {
"desc": {
"value": "引用"
}
}
}
],
# 不写的话默认为1(即shoule的所有条件中,
# 只要有1个条件满足,那么即判定该文档匹配)
# =2的话即代表所有条件中
# 必须有>=2个条件满足才判断匹配成功
"minimum_should_match": 1
}
}
}
- must_not(not)返回的文档必须不满足定义的所有条件
# 查询文档中desc没有“美国”且没有“修养”的记录
GET /dangdang/books/_search
{
"query": {
"bool": {
"must_not": [
{
"term": {
"desc": {
"value": "美国"
}
}
},
{
"term": {
"desc": {
"value": "修养"
}
}
}
]
}
}
}
- filter 返回的文档必须满足filter子句的条件,但是不参与计算分值
# 查找文档中desc包含“人”的记录
GET /dangdang/books/_search
{
"query": {
"bool": {
"filter": {
"term": {
"desc": "人"
}
}
}
}
}
组合查询
非常需要注意的点:
在组合查询中,即由must、must not、filter、should组合而成的bool查询,有一个很重要的点时,当使用should查询时,且除了should查询之外还有must、filter中的任意一个时(也可以must、filter同时都有),should的条件默认会被自动忽略(即minimum_should_match此时被设置成0)。
举个简单的例子,现要查询文档中a=1,b=2,(c=8或c=9)的记录,此时可能会这么写:
GET /dangdang/books/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"a": {
"value": "1"
}
}
},
{
"term": {
"b": {
"value": "2"
}
}
}
],
"should": [
{
"term": {
"c": {
"value": "8"
}
}
},
{
"term": {
"c": {
"value": "9"
}
}
}
]
}
}
}
但是结果会跟实际预期的不一样,当有should又有must/filter时,如果一条记录满足a=1,b=2,但即使c=999,该记录依然会被匹配成功,即should的条件会被视为无效,相当于minimum_should_match=0。如果想要达到预期的效果,可以将minimum_should_match设置为1,此时是满足该需求的。
GET /dangdang/books/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"a": {
"value": "1"
}
}
},
{
"term": {
"b": {
"value": "2"
}
}
}
],
"should": [
{
"term": {
"c": {
"value": "8"
}
}
},
{
"term": {
"c": {
"value": "9"
}
}
}
],
# 满足should所有条件中的一个
"minimum_should_match": 1
}
}
}
嵌套bool查询
# 筛选出desc包含“人”且包含“鬼”的记录,
# 且记录中至少包含了“蔡元培”,“中国人”,
# “引用” 条件中至少2个条件的记录
GET /dangdang/books/_search
{
"query": {
"bool": {
"filter": {
"bool": {
"must": [
{
"term": {
"desc": {
"value": "人"
}
}
},
{
"term": {
"desc": {
"value": "鬼"
}
}
}
]
}
},
"should": [
{
"term": {
"desc": {
"value": "引用"
}
}
},
{
"term": {
"desc": {
"value": "中国人"
}
}
},
{
"term": {
"desc": {
"value": "蔡元培"
}
}
}
],
"minimum_should_match": 2
}
}
}
网友评论