814 字
约 2 分钟
7
S13-B03 · 查询 DSL 与客户端

适用读者:写过 match 但不知道为什么"有时搜不到"的人。
前置:S13-B02。
实测环境:ES 8.15.3(2026-11-05)。
覆盖旧文:481(RestHighLevelClient 入门,34 点)。
覆盖扩展:E-S13-004(四类查询的边界)。
上一篇:S13-B02 · 索引映射与中文分词
下一篇:S13-J01 · 索引调优。


1. 一句话结论

查询 DSL 的两个轴:query(打分,影响相关性)与 filter(不打分,可缓存)。四类叶子查询:term、match、range、bool。


2. 实测:term 与 match 的关键差异

查询 结果 原因
match: title="Tutorial" 1 会走分析器(小写化)
term: title="Tutorial" 0 不分词、不改大小写
term: title="tutorial" 1 token 本来就是小写
term: tag="search"(keyword) 1 keyword 适合 term
match_phrase: "elasticsearch tutorial" 1 顺序一致
match_phrase: "tutorial elasticsearch" 0 顺序敏感

"term 该用在哪":keyword 字段的精确匹配(如 tag、status、userId)。用在 text 字段上是最常见的坑。


3. query 与 filter 的分工

上下文 是否打分 缓存 用途
query(must/should) ✅ ❌ 相关性排序
filter(filter/must_not) ❌ ✅ 精确过滤(状态、时间、权限)

实测(bool):

{"query":{"bool":{"must":[{"term":{"tag":"search"}}],
                  "filter":[{"range":{"views":{"gte":50}}}]}}}
hits = 1

判据:"这个条件影响相关度吗?" 不影响 → 放 filter(更快、可缓存)。


4. 排序与分页

手段 说明 坑
sort 按字段/相关度排序 text 字段不能直接排序(用 keyword)
from/size 分页 深翻有上限(index.max_result_window 默认 10000)
search_after 游标分页 需稳定的唯一排序字段
scroll 大批量导出 占资源,不适合用户交互

"深翻为什么有上限":ES 要维护每分片的 top-N 堆,过深会拖垮内存——与 S11-B03 的深翻同理,但ES 是硬限制,不是变慢。


5. 客户端的选择(A-481)

客户端 状态
RestHighLevelClient(7.x) 7.15 起标记弃用
ElasticsearchClient(8.x 新 Java client) 推荐
spring-data-elasticsearch 适合 Spring 项目
直接 HTTP + JSON 最灵活,适合排障

判据:"团队用 Spring 吗?" 用 → spring-data;否则用官方新 client。


6. 五个误区

误区 真相
"term 能查文本内容" 不分词,通常查不到
"filter 和 must 等价" filter 不打分、可缓存
"text 字段能排序" 需要 keyword
"分页可以无限深" 默认上限 10000
"match_phrase 忽略顺序" 顺序敏感(实测反序 0 命中)

7. 自检

  1. term 与 match 的本质差异?
  2. term 该用在什么字段上?
  3. query 与 filter 怎么分工?
  4. 深翻为什么有硬上限?
  5. ES 8 推荐哪个 Java 客户端?

8. 下一篇

S13-J01 · 索引调优:mapping、refresh、段合并

查询讲完,进阶层开始:写入为什么慢、段合并为什么重要。


本篇属于系列《S13 · 搜索与文档存储》。旧文来源:A-481;扩展点 E-S13-004。命中数为 ES 8.15.3 实测。

S13-B03 · 查询 DSL 与客户端
https://www.clxhxhhr.top/posts/5362/
作者
clxstart
发布于
2024-12-31
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。