Skip to content

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

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions