ElasticSearch bool多条件查询(must、must not、should、filter)

说明

bool 查询(布尔查询)是 Elasticsearch 中最常用的复合查询,通过逻辑运算符 组合多个子查询,实现复杂的条件过滤与评分控制。

子句

  • must:必须匹配,相当于 SQL 中的 and
  • must not:必须不匹配,相当于 SQL 中的 not,如:not in、not like
  • should:可以匹配修饰,相当于 sql中的 or
  • filter:过滤器,处理 比较运算,如: 大于、小于

对比

子句类型 逻辑作用 对得分的影响 是否必须满足
must 逻辑与(AND) 贡献得分(匹配度越高得分越高) 是
must_not 逻辑非(NOT) 不贡献得分 是(必须不满足)
should 逻辑或(OR) 贡献得分(满足越多得分越高) 否(除非无 must/filter)
filter 逻辑与(AND) 不贡献得分(得分固定为 1) 是

语法

{
    "bool": {
        "must":     { "match": { "status": 1 }},
        "must_not": { "match": { "language":  "french" }},
        "should":   { "match": { "author": "John Tom" }},
        "filter":   { "range": { "length" : { "gt" : 30 }} }
    }
}

得分计算逻辑

bool 查询的最终得分由以下部分组成:

  1. must 和 should 子句的得分总和:每个子查询的得分(如 match 的相关性得分)相加;
  2. 归一化处理:根据满足的 should 子句数量进行归一化(满足越多,单句得分权重越高);
  3. filter 和 must_not 不影响得分:仅过滤文档,不参与评分。

must 多条件同时成立

所有 must 子句的条件必须同时满足,且每个子句的匹配度会参与最终得分计算。

提示:相当于 SQL 中的 and

代码

GET /toutiao_v1/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match_phrase": {
            "title": "入门"
          }
        },
        {
          "match_phrase": {
            "content": "技巧"
          }
        }
      ]
    }
  }
}

执行结果:

must_not 多条件同时不满足

所有 must_not 子句的条件必须都不满足,不参与得分计算。

GET /your_index/_search
{
  "query": {
    "bool": {
      "must": [{ "match": { "title": "性能优化" } }],
      "must_not": [
        { "term": { "author": "匿名" } },
        { "range": { "publish_time": { "lt": "2023-01-01" } } }
      ]
    }
  }
}

should 多条件成立一个

满足任意 should 子句即可,满足数量越多得分越高。特殊规则:

  • 若存在 must/filter,should 可选(不满足也可返回);
  • 若无 must/filter,至少需满足一个 should(否则无结果);
  • 可通过 minimum_should_match 强制满足数量(如 2 或 "75%")。

提示:相当于sql中的 or

代码

GET /toutiao_v1/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "title": "mysql"
          }
        },
        {
          "match": {
            "content": "高手"
          }
        }
      ]
    }
  }
}

查询结果如下图:

filter

ElasticSearch 比较查询:filter、must、range(大于、小于)

高级用法

结合 boost 调整权重

通过 boost 参数提升/降低某个子句的得分权重:

GET /your_index/_search
{
  "query": {
    "bool": {
      "should": [
        { "match": { "title": { "query": "Elasticsearch", "boost": 3 } } }, // 权重×3
        { "match": { "content": { "query": "Elasticsearch", "boost": 1 } } }
      ]
    }
  }
}

多层嵌套 bool

GET /your_index/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "content": "云计算" } },
        {
          "bool": { // 嵌套bool
            "should": [
              { "match": { "tags": "AWS" } },
              { "match": { "tags": "阿里云" } }
            ],
            "must_not": [{ "term": { "tags": "过时" } }]
          }
        }
      ],
      "filter": [{ "term": { "status": "published" } }]
    }
  }
}

性能优化建议

  1. 优先用 filter 做过滤:filter 结果会被缓存,重复查询时性能更高;
  2. 减少 must_not 嵌套:must_not 需要遍历排除,数据量大时尽量放在外层;
  3. 控制 should 数量:过多 should 子句会增加计算量,必要时用 minimum_should_match 限制;
  4. 避免深度嵌套:多层嵌套 bool 会增加查询复杂度,尽量扁平化结构。

总结

  1. 核心逻辑:bool 查询通过 must/filter/should/must_not 实现多条件组合,灵活控制匹配规则;
  2. 得分关键:must/should 影响得分,filter/must_not 仅过滤;
  3. 性能优化:优先用 filter 做高频过滤,合理控制嵌套深度和子句数量。

原文出处:/show_1IX1mBBF35cT.html