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. 自检
term与match的本质差异?term该用在什么字段上?query与filter怎么分工?- 深翻为什么有硬上限?
- 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/ 评论
0 条
还没有评论,先写一条吧。