查询与相关性打分
用途:写出既准又快的查询,并解释排序结果为什么不符合预期
两类子句:query vs filter
「两类子句:query vs filter」小节链接| 子句 | 是否打分 | 是否可缓存 | 用法 |
|---|---|---|---|
must / should(query 上下文) |
是(BM25) | 部分 | 需要相关性排序的全文条件 |
filter(filter 上下文) |
否 | 是(节点级缓存) | 状态、时间范围、租户、权限 |
性能第一原则:把不需要打分条件的部分全部放进 filter(枚举、范围、存在性),既省算力又能命中缓存。
常用查询
「常用查询」小节链接| 查询 | 场景 |
|---|---|
match |
分词后检索(默认 OR + minimum_should_match 控制严格度) |
match_phrase |
短语/邻近(slop) |
multi_match (best_fields/most_fields/cross_fields) |
多字段综合搜索 |
term / terms |
keyword 精确匹配(放 filter) |
range |
时间/数值区间 |
exists |
字段存在性 |
bool 组合 |
主结构:must / should / must_not / filter |
nested |
数组内对象整体匹配 |
function_score / script_score |
业务分叠加(热度、时间衰减、运营权重) |
search_as_you_type / completion |
前缀补全与联想 |
knn |
向量相似检索(语义搜索场景) |
相关性调优顺序
「相关性调优顺序」小节链接- 先做对:字段映射与分析器正确(中文分词、同义词、
keyword子字段)。 - 再做过滤:状态、权限、时间用 filter,不参与打分。
- 然后调权:字段权重(
boost)、tie_breaker、minimum_should_match。 - 最后叠业务分:
function_score组合高斯时间衰减、热度对数、运营标记。 - 评估:用
explain看单文档得分来源;用带标注的查询集做离线排序评估(nDCG/MRR),不要靠肉眼。
分页与深分页
「分页与深分页」小节链接| 方式 | 适用 | 限制 |
|---|---|---|
from + size |
前几页 | 受 index.max_result_window(默认 10000)限制;每分片都要取 from+size 再归并,越深越贵 |
search_after |
翻页/导出 | 需要排序键唯一(加 _id 兜底),不能跳页 |
scroll |
全量遍历(批处理) | 占用上下文,不适合实时分页,逐步被 PIT + search_after 取代 |
PIT + search_after |
一致性快照下的深分页 | 需管理 PIT 生命周期 |
产品层建议限制可翻页深度(如最多 100 页),更深需求改成交互条件收窄或导出任务。
一致性快照
「一致性快照」小节链接多请求翻页时数据可能变化导致重复/漏项。用 Point In Time(PIT) 固定视图,配合 search_after 保证翻页稳定。
常见误区
「常见误区」小节链接| 误区 | 修正 |
|---|---|
| 所有条件都放 must | 无谓打分 + 无法缓存 |
用 wildcard/前导通配做常规搜索 |
极慢,改 ngram 或 keyword + 精确 |
| 排序字段用 text | 用 keyword 或 doc_values 字段 |
深分页 from=50000 |
改 search_after 或收窄条件 |
| 相关性差就加脚本打分 | 先查映射与分析器,脚本打分成本高 |
| 不做评估集就调参 | 改动无法判断好坏,容易越调越差 |
延伸阅读
「延伸阅读」小节链接- Elasticsearch 官方文档:Query DSL、Relevance、PIT & search_after
- 《Relevant Search》(相关性工程方法)