文章

Elasticsearch中Bool查询

Bool 查询详解

1. Bool 查询的本质

Bool 查询是一个复合查询容器,它允许你组合多个查询条件,通过布尔逻辑(AND、OR、NOT)将它们关联起来。它包含四种类型的子句:

  • must:文档必须匹配这些条件,且会影响评分

  • filter:文档必须匹配这些条件,但不影响评分

  • should:文档应该匹配这些条件,匹配会提高评分

  • must_not:文档不能匹配这些条件

2. Bool 查询可以包含的子查询类型

Bool 查询可以包含任何类型的查询作为其子句,包括但不限于:

子查询类型

适用字段类型

用途

match

主要用于 text

全文搜索

term

主要用于 keyword、数值、布尔等

精确匹配

range

数值、日期

范围查询

exists

任何类型

字段存在性检查

wildcard

主要用于 keyword

通配符匹配

prefix

主要用于 keyword

前缀匹配

另一个 bool

任何类型

嵌套布尔逻辑

3. Bool 查询示例

混合字段类型的 Bool 查询

GET /products/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "description": "高性能无线"  // text 类型,使用 match 查询
          }
        }
      ],
      "filter": [
        {
          "term": {
            "brand.keyword": "Apple"  // keyword 类型,使用 term 查询
          }
        },
        {
          "range": {
            "price": {  // 数值类型,使用 range 查询
              "gte": 1000,
              "lte": 3000
            }
          }
        }
      ],
      "should": [
        {
          "term": {
            "tags.keyword": "热销"  // keyword 类型,使用 term 查询
          }
        }
      ],
      "must_not": [
        {
          "term": {
            "status": "discontinued"  // keyword 类型,使用 term 查询
          }
        }
      ]
    }
  }
}

嵌套 Bool 查询

GET /articles/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "content": "elasticsearch 查询优化"  // text 类型
          }
        }
      ],
      "filter": [
        {
          "bool": {  // 嵌套 bool 查询
            "should": [
              {
                "term": {
                  "category.keyword": "技术"  // keyword 类型
                }
              },
              {
                "term": {
                  "category.keyword": "编程"  // keyword 类型
                }
              }
            ]
          }
        },
        {
          "range": {
            "publish_date": {  // 日期类型
              "gte": "now-1y"
            }
          }
        }
      ]
    }
  }
}

Bool 查询与 Match 查询的区别

1. 层级和用途不同

  • Match 查询:是一种叶子查询(leaf query),直接操作特定字段

  • Bool 查询:是一种复合查询(compound query),组合多个查询条件

2. 适用场景不同

  • Match 查询:主要用于单个 text 类型字段的全文搜索

  • Bool 查询:用于构建复杂的查询逻辑,组合多个条件

3. 示例对比

Match 查询

GET /books/_search
{
  "query": {
    "match": {
      "title": "elasticsearch 实战指南"
    }
  }
}

Bool 查询

GET /books/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "title": "elasticsearch"
          }
        },
        {
          "match": {
            "content": "性能优化"
          }
        }
      ],
      "filter": [
        {
          "range": {
            "publish_date": {
              "gte": "2020-01-01"
            }
          }
        }
      ]
    }
  }
}

常见误解与澄清

误解 1:Bool 查询只用于 text 类型字段

澄清:Bool 查询可以包含针对任何类型字段的子查询。

误解 2:Bool 查询等同于多个 Match 查询的组合

澄清:虽然 Bool 查询可以组合多个 Match 查询,但它也可以组合任何其他类型的查询。

误解 3:Bool 查询中的所有子句都影响评分

澄清

  • mustshould 子句会影响文档的评分

  • filtermust_not 子句只用于过滤,不影响评分

Bool 查询的实际应用场景

1. 电商产品搜索

这是一个典型的电商网站产品搜索场景,用户在搜索框中输入"智能手机 高性能",并通过筛选条件选择了华为品牌、2000-6000元价格区间、只看有货商品。

GET /products/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "multi_match": {
            "query": "智能手机 高性能",
            "fields": ["name^3", "description"]
          }
        }
      ],
      "filter": [
        {
          "term": {
            "brand.keyword": "华为"
          }
        },
        {
          "range": {
            "price": {
              "gte": 2000,
              "lte": 6000
            }
          }
        },
        {
          "term": {
            "in_stock": true
          }
        }
      ],
      "should": [
        {
          "term": {
            "tags.keyword": "新款"
          }
        },
        {
          "term": {
            "tags.keyword": "热销"
          }
        }
      ]
    }
  }
}

2. 内容推荐系统

这是一个内容平台(如技术博客、新闻网站)的文章推荐场景,系统需要根据用户兴趣(人工智能和机器学习)推荐相关的最新文章。

GET /articles/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "content": "人工智能 机器学习"
          }
        }
      ],
      "filter": [
        {
          "range": {
            "publish_date": {
              "gte": "now-30d"
            }
          }
        }
      ],
      "should": [
        {
          "term": {
            "author.keyword": "张三"
          }
        },
        {
          "terms": {
            "tags.keyword": ["AI", "深度学习", "神经网络"]
          }
        }
      ],
      "must_not": [
        {
          "term": {
            "is_draft": true
          }
        }
      ]
    }
  }
}

总结

  1. Bool 查询是通用的:Bool 查询是一个复合查询容器,不专属于任何特定字段类型

  2. 可以包含任何子查询

    • text 类型字段可以使用 matchmatch_phrase 等查询

    • keyword、数值类型等可以使用 termrange 等查询

  3. 灵活组合:可以通过 mustshouldfiltermust_not 灵活组合各种查询条件

  4. 评分与过滤:可以同时处理影响评分的条件和纯过滤条件

Bool 查询的强大之处在于它的灵活性和组合能力,可以构建从简单到复杂的各种查询逻辑,适用于各种业务场景。

License:  CC BY 4.0