-
Notifications
You must be signed in to change notification settings - Fork 1
Open
Labels
Description
情景
- 单纯只有 should 的时候,命中结果有 19 条
{
"query": {
"bool": {
"should": [
{
"match": {
"address": "mill"
}
},
{
"match": {
"address": "lane"
}
}
]
}
}
}- 当加上 filter 条件之后,命中结果有 217 条
{
"query": {
"bool": {
"should": [
{
"match": {
"address": "mill"
}
},
{
"match": {
"address": "lane"
}
}
],
"filter": {
"range": {
"balance": {
"gte": 20000,
"lte": 30000
}
}
}
}
}
}明明 2 中 filter 添加了进一步的过滤条件,预期只会返回更少的数据。
但是返回的结果范围却远远超出预期,多出来好多条件不符合的数据。
这到底是为什么呢?
原因说明
这是因为在 should 在单独使用时,默认一个文档要被命中的条件是:至少匹配 should 条件中的其中一个条件
当 should 和 filter 一起使用使用时 (如 2 中的示例),这个时候 should 的所有条件都变成了 ”可选“。
换句话说,这个时候有 should 和没有 should 是一样的,起到作用的只剩下 filter 里面的条件了。
这就是为啥 2 中返回的数据,反倒比 1 中的更多
解决办法
设置 minimum_should_match 来解决这个问题。
{
"query": {
"bool": {
"should": [
{
"match": {
"address": "mill"
}
},
{
"match": {
"address": "lane"
}
}
],
"minimum_should_match": 1,
"filter": {
"range": {
"balance": {
"gte": 20000,
"lte": 30000
}
}
}
}
}
}通过设置 "minimum_should_match": 1 来限定 should 的命中条件为 ”文档必须至少满足一个 should 条件的匹配“。
这样,filter 就能在 should 筛选出的结果中继续过滤,而不会直接忽略 should 条件。
当然,minimum_should_match 还可以设置为其他大小,具体要看你需要的 should 中至少满足多少个条件匹配。
最后
参考 Elasticsearch 官方论坛:https://discuss.elastic.co/t/combine-should-with-filter-search-api/139129