Elasticsearch Query DSL 中 must / filter / should 详解

Elasticsearch Query DSL 中 must / filter / should 详解(面试 & 实战必会)

这是 Java 高级工程师面试中 Elasticsearch 几乎必问的一题

很多人"会写 DSL",但说不清为什么这么写、性能差在哪、线上怎么选

这篇文档的目标:让你能写、能讲、能反问面试官


1. must / filter / should 是什么?

它们都属于 bool query 的子句,用来组合多个条件。

json 复制代码
{
  "query": {
    "bool": {
      "must":   [],
      "filter": [],
      "should": []
    }
  }
}

一句话先记住:

must = 必须匹配 + 参与打分
filter = 必须匹配 + 不打分(可缓存)
should = 可选匹配 + 影响打分


2. must:必须匹配,参与相关性打分

2.1 基本含义

  • 条件 必须满足
  • 参与 _score 计算
  • 常用于 全文检索

2.2 示例

json 复制代码
{
  "query": {
    "bool": {
      "must": [
        { "match": { "title": "elasticsearch" } }
      ]
    }
  }
}

2.3 适合放在 must 的查询

  • match
  • match_phrase
  • multi_match
  • 任何需要 相关性排序 的条件

2.4 面试加分点(为什么 must 慢)

  • must 会参与 BM25 打分
  • 每个文档都要算 score
  • 在只做过滤时是纯浪费

👉 能不用 must 就别用 must


3. filter:必须匹配,但不参与打分(性能王者)

3.1 基本含义

  • 条件 必须满足
  • 不计算 _score
  • 结果可被缓存

3.2 示例

json 复制代码
{
  "query": {
    "bool": {
      "filter": [
        { "term": { "status": "ON" } },
        { "range": { "price": { "gte": 100, "lte": 500 } } }
      ]
    }
  }
}

3.3 适合放在 filter 的查询

  • term / terms
  • range
  • exists
  • ids

3.4 filter 为什么快?

  • 不算 score
  • 可缓存(尤其是低基数条件)
  • 多 shard 场景下优势明显

3.5 面试标准话术

精准条件、与相关性无关的,一律放 filter。


4. must vs filter 的真实对比(高频面试点)

对比项 must filter
是否必须匹配
是否算 score
是否可缓存
性能 较慢 很快
典型用途 全文检索 精准过滤

5. should:可选匹配,用来"加分"

5.1 基本含义

  • 不是必须匹配
  • 匹配到的文档 score 更高
  • 常用于 相关性优化

5.2 示例

json 复制代码
{
  "query": {
    "bool": {
      "must": [
        { "match": { "title": "java" } }
      ],
      "should": [
        { "match": { "tags": "elasticsearch" } },
        { "match": { "tags": "search" } }
      ]
    }
  }
}

👉 匹配 title=java 就能进结果

👉 同时匹配 tags 的会排得更靠前


5.3 minimum_should_match(面试常追问)

json 复制代码
{
  "bool": {
    "should": [
      { "term": { "color": "red" } },
      { "term": { "size": "L" } },
      { "term": { "brand": "nike" } }
    ],
    "minimum_should_match": 2
  }
}

含义:

  • 3 个 should 条件
  • 至少满足 2 个

6. should 在不同场景下的"隐藏规则"(必会)

6.1 只有 should(没有 must / filter)

json 复制代码
{
  "bool": {
    "should": [
      { "term": { "status": "ON" } },
      { "term": { "status": "OFF" } }
    ]
  }
}

👉 至少匹配 1 个 should(默认)


6.2 有 must / filter + should

json 复制代码
{
  "bool": {
    "must": [
      { "match": { "title": "java" } }
    ],
    "should": [
      { "term": { "tags": "es" } }
    ]
  }
}

👉 should 不再是必须条件

👉 只影响排序


7. 一个"标准工程级写法"(面试直接背)

json 复制代码
{
  "query": {
    "bool": {
      "must": [
        { "match": { "name": "iphone" } }
      ],
      "filter": [
        { "term": { "status": "ON" } },
        { "range": { "price": { "gte": 1000 } } }
      ],
      "should": [
        { "term": { "tags": "hot" } },
        { "term": { "tags": "new" } }
      ]
    }
  }
}

解释给面试官听:

  • must:决定"搜什么"
  • filter:决定"能不能进"
  • should:决定"谁排前面"

8. Spring Boot 中的对应写法(加分)

java 复制代码
BoolQueryBuilder bool = QueryBuilders.boolQuery()
    .must(QueryBuilders.matchQuery("name", "iphone"))
    .filter(QueryBuilders.termQuery("status", "ON"))
    .filter(QueryBuilders.rangeQuery("price").gte(1000))
    .should(QueryBuilders.termQuery("tags", "hot"))
    .should(QueryBuilders.termQuery("tags", "new"));

9. 高频踩坑总结(面试官最爱)

  • ❌ 全部条件都放 must(性能差)
  • ❌ term 查询放 must(浪费 score)
  • ❌ 以为 should 一定要匹配(不是)
  • ❌ 忘了 minimum_should_match

10. 一句话总结(背这个就够)

must 决定"相关性",
filter 决定"对不对",
should 决定"谁更好"。
能 filter 就 filter,
少算 score,ES 才跑得快。

相关推荐
week_泽5 小时前
github_upload,上传项目
大数据·elasticsearch·github
CNRio6 小时前
Day 35:Git的分支管理:理解分支的创建、切换与合并
大数据·git·elasticsearch
CodeAmaz8 小时前
Spring Boot 项目使用 Elasticsearch 详细指南
spring boot·后端·elasticsearch
CNRio9 小时前
Day 12:Git配置详解:用户信息、编辑器、颜色等配置
git·elasticsearch·编辑器
Elastic 中国社区官方博客9 小时前
如何使用 LangChain 和 Elasticsearch 构建 agent 知识库
大数据·人工智能·elasticsearch·搜索引擎·ai·langchain·全文检索
Elastic 中国社区官方博客17 小时前
使用 Elastic Cloud Serverless 扩展批量索引
大数据·运维·数据库·elasticsearch·搜索引擎·云原生·serverless
Dxy123931021618 小时前
Elasticsearch 8.13.4 内存占用过大如何处理
大数据·elasticsearch·搜索引擎
K_Men1 天前
springboot 接入Elasticsearch的聚合查询
spring boot·elasticsearch·jenkins
Elasticsearch1 天前
如何使用 LangChain 和 Elasticsearch 构建 agent 知识库
elasticsearch