Elasticsearch:复合查询bool

83 阅读4分钟

一、Bool 查询概述

Bool 查询是 Elasticsearch 中最重要且最常用的复合查询,它允许通过逻辑组合将多个查询子句合并成一个查询。Bool 查询包含四种主要的子句类型:

子句类型描述类比逻辑运算符是否影响评分
must所有条件必须满足AND
should至少满足一个条件OR
must_not必须不满足条件NOT
filter必须满足条件(不评分)AND

二、核心参数详解

1. minimum_should_match

作用:控制 should 子句的最小匹配数量

取值格式

  • 整数:2(必须匹配2条)
  • 负数:-1(总条件数-1)
  • 百分比:75%(匹配75%的条件)
  • 组合条件:3<90%(≤3条件需全匹配,>3匹配90%)

示例

{
  "query": {
    "bool": {
      "should": [
        { "match": { "title": "Elasticsearch" } },
        { "match": { "content": "Kibana" } },
        { "match": { "tags": "数据分析" } }
      ],
      "minimum_should_match": 2
    }
  }
}

2. disable_coord

作用:禁用查询协调因子(默认启用)

使用场景

  • 当不需要考虑查询词项在文档中的分布密度时
  • 需要更简单的评分模型时

协调因子计算公式:

coord = (匹配的词项数量) / (查询中的总词项数量)

示例


{
  "query": {
    "bool": {
      "must": [
        { "match": { "title": "分布式搜索" } }
      ],
      "disable_coord": true
    }
  }
}

3. adjust_pure_negative

作用:控制纯否定查询的评分调整(默认true)

示例

{
  "query": {
    "bool": {
      "must_not": [
        { "term": { "status": "deprecated" } }
      ],
      "adjust_pure_negative": false
    }
  }
}

4. boost

作用:设置查询权重

典型值

  • 1.0:默认权重
  • >1.0:提高重要性
  • <1.0:降低重要性

示例

json

{
  "query": {
    "bool": {
      "should": [
        { "match": { "title": { "query": "Elasticsearch", "boost": 2.0 } } },
        { "match": { "content": "Kibana" } }
      ]
    }
  }
}

三、子句类型深度解析

1. must 子句

特点

  • 所有条件必须满足
  • 参与相关性评分
  • 可包含任意数量条件

典型应用

json

{
  "query": {
    "bool": {
      "must": [
        { "term": { "category": "技术书籍" } },
        { "range": { "price": { "gte": 50, "lte": 200 } } },
        { "match": { "author": "张三" } }
      ]
    }
  }
}

2. should 子句

行为规则

上下文环境匹配要求
单独使用至少匹配1条
与must/filter共存可选匹配(只影响评分)
在filter内使用至少匹配1条

示例

json

{
  "query": {
    "bool": {
      "must": [
        { "term": { "in_stock": true } }
      ],
      "should": [
        { "match": { "title": "入门指南" } },
        { "match": { "description": "初学者" } }
      ],
      "minimum_should_match": 1
    }
  }
}

3. must_not 子句

特点

  • 排除匹配文档
  • 不参与评分
  • 性能优于同等should查询

示例

json

{
  "query": {
    "bool": {
      "must_not": [
        { "term": { "category": "儿童读物" } },
        { "range": { "publication_date": { "lt": "2020-01-01" } } }
      ]
    }
  }
}

4. filter 子句

优势

  • 不计算评分,性能更高
  • 结果可缓存
  • 适用于精确过滤

典型场景

json

{
  "query": {
    "bool": {
      "filter": [
        { "term": { "user_id": 12345 } },
        { "range": { "login_time": { "gte": "now-1d/d" } } }
      ]
    }
  }
}

四、嵌套查询实践

1. 多层嵌套示例

json

{
  "query": {
    "bool": {
      "must": [
        {
          "bool": {
            "should": [
              { "match": { "title": "Elasticsearch" } },
              { "match": { "title": "搜索引擎" } }
            ]
          }
        },
        {
          "bool": {
            "must": [
              { "term": { "language": "中文" } },
              { "range": { "page_count": { "gte": 100 } } }
            ]
          }
        }
      ],
      "must_not": {
        "term": { "edition": "试用版" }
      }
    }
  }
}

2. 混合使用模式

json

{
  "query": {
    "bool": {
      "must": [
        { "match": { "content": "大数据" } }
      ],
      "should": [
        { "term": { "featured": true } },
        {
          "bool": {
            "must": [
              { "exists": { "field": "attachments" } },
              { "range": { "rating": { "gte": 4 } } }
            ]
          }
        }
      ],
      "filter": [
        { "term": { "category": "技术文章" } },
        { "range": { "publish_date": { "gte": "2023-01-01" } } }
      ],
      "minimum_should_match": 1
    }
  }
}

五、性能优化建议

  1. filter优先原则

    • 将不关心评分的条件放入filter
    • 利用查询缓存提升性能
  2. should子句控制

    • 明确设置minimum_should_match
    • 避免过多可选条件
  3. 评分优化

    • 对重要字段使用boost
    • 合理使用disable_coord
  4. 嵌套查询建议

    • 控制嵌套深度(一般不超过3层)
    • 将高选择性的条件放在内层
  5. 监控指标

    json

    GET /_search?request_cache=true
    {
      "profile": true,
      "query": {
        "bool": {
          // 您的查询
        }
      }
    }
    

六、常见问题解决方案

问题1:should子句不生效

  • 检查是否在must/filter上下文中使用
  • 确认minimum_should_match设置

问题2:查询性能差

  • 将range查询移到filter中
  • 减少嵌套层级

问题3:评分不符合预期

  • 检查boost值设置
  • 考虑禁用coord因素

问题4:结果过滤不准确

  • 确认字段映射类型(keyword vs text)
  • 检查分析器是否合适

问题5:既然有了must,为啥还要有filter,这2个不是都必须匹配的吗

特性mustfilter
是否影响评分是(参与相关性计算)否(不参与评分)
查询缓存不可缓存可缓存
执行效率较低(需要计算评分)较高(只需过滤)
使用场景影响搜索结果排序的核心条件不影响排序的精确过滤条件
查询类型支持全文检索和精确查询主要用于精确匹配和范围查询

通过掌握bool查询的这些高级用法和优化技巧,您可以构建出既精确又高效的Elasticsearch查询,满足各种复杂的业务搜索需求。