Skip to content

elasticsearch should 条件下得到的结果异常 or the elasticsearch should condition not working as expected #118

@lanlin

Description

@lanlin

情景

  1. 单纯只有 should 的时候,命中结果有 19 条
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "address": "mill"
          }
        },
        {
          "match": {
            "address": "lane"
          }
        }
      ]
    }
  }
}
  1. 当加上 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

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions