用 ES|QL 做搜索从过滤到相关性、再到语义与混合检索
一、过滤 vs. 搜索
- 过滤(filtering):只决定“是否匹配”,不算分,速度快,适合精确条件/范围/布尔逻辑。
- 搜索(searching):先过滤,再按相关性给结果打分与排序;会用到分词、同义词、模糊等文本分析。
在 ES|QL 中,是否“按相关性排序”由你显式决定:加METADATA _score
开启评分,并用SORT _score DESC
才会看到“最相关在前”。否则即便用了MATCH
这类函数,也只是过滤不排序。(Elastic)
二、版本时间线(速查)
能力 | 说明 | 首次提供 |
---|---|---|
MATCH / : | 基础全文匹配(函数与冒号运算符两种写法) | 8.17 (Elastic) |
QSTR() | Query String 语法的函数版 | 8.17 (Elastic) |
相关性评分 | METADATA _score + SORT _score | 8.18/9.0 (Elastic) |
语义检索 | 在 semantic_text 字段上使用搜索函数 | 8.18/9.0 (Elastic) |
混合检索 | 词法 + 语义,自定义权重 | 8.18/9.0 (Elastic) |
KQL() | 在 ES|QL 里复用 Kibana Query Language | 8.18/9.0 (Elastic) |
MATCH_PHRASE() | 等价 DSL 的 match_phrase | 8.19/9.1 (Elastic) |
参考:Elastic 官方“ES|QL for search”与发布/实验室文章。(Elastic)
三、写法速通:最常用 6 种
约定:
FROM index
开头,WHERE
里放条件,LIMIT
控制条数。
A. 基础全文匹配(MATCH
/ :
)
FROM my_index METADATA _score
| WHERE MATCH(content, "quick brown fox")
| SORT _score DESC
| LIMIT 10
-- 等价简写:
-- FROM my_index METADATA _score | WHERE content : "quick brown fox" | SORT _score DESC | LIMIT 10
评分与排序靠 _score
启用与降序排序。(Elastic)
B. 短语匹配(MATCH_PHRASE
)
FROM articles METADATA _score
| WHERE MATCH_PHRASE(title, "open source license")
| SORT _score DESC
等价于 DSL 的 match_phrase
。(Elastic)
C. Query String(QSTR()
)
FROM docs METADATA _score
| WHERE QSTR('title:(golang OR "go lang") AND -status:archived')
| SORT _score DESC
保留 DSL query_string
的复杂表达力(通配、布尔、多字段)。(Elastic)
D. KQL(KQL()
)
FROM logs METADATA _score
| WHERE KQL('status.code >= 500 and service.name : "api*"')
| SORT _score DESC
便于从 Kibana 迁移查询到 ES|QL。(Elastic)
E. 语义检索(semantic_text
)
FROM knowledge_base METADATA _score
| WHERE MATCH(semantic_body, "how to reset a lost password?")
| SORT _score DESC
| LIMIT 5
把字段映射为 semantic_text
后,即可用与全文一致的写法执行语义检索;嵌入生成与切分由后端托管。(Elastic)
F. 混合检索(语义 + 词法,权重可配)
FROM cooking_blog METADATA _score
| WHERE MATCH(semantic_description, "easy vegetarian meals", { "boost": 0.75 })OR MATCH(tags, "vegetarian", { "boost": 0.25 })
| SORT _score DESC
| LIMIT 5
实战里可做线性加权或 RRF 等融合策略,这里展示线性权重。(Elastic)
四、何时选“过滤”,何时选“搜索”?
选过滤(快):精确类目(category.keyword="Electronics"
)、时间/数值范围、布尔组合、你只关心“全匹配集合”。
选搜索(准):自然语言查询、需要“最佳命中在前”、需要分词/同义词/模糊。
在 ES|QL 里,同一条语句可以先 WHERE
做过滤,再 MATCH
搜索并按 _score
排序,做到“先粗后精”。(Elastic)
五、与 Query DSL 的关系与迁移建议
- 多数 DSL 搜索能力在 ES|QL 里都有“函数等价物”:
match
→MATCH()
/:
、match_phrase
→MATCH_PHRASE()
、query_string
→QSTR()
、Kibana 查询→KQL()
。(Elastic) - 迁移时先等价替换,再显式加上
METADATA _score | SORT _score DESC
才能得到相关性排序。(Elastic) - 需要纯 DSL 的语义查询(
semantic
query)也可用在 DSL;而在 ES|QL 里,建议直接用semantic_text
+MATCH
/混合检索。(Elastic)
六、语义与混合检索的工程要点
semantic_text
映射:自动做嵌入生成与长文本切分,显著简化管线(无需手写推理 pipeline)。(Elastic)- 混合策略:线性加权(如上示例)简单直观;RRF 等融合也常见,适合跨模态/跨通道的结果合并。(Elastic)
- 可观测与韧性:8.19/9.1 增强了 ES|QL 的可观测与容错能力,适合在大规模查询中落地。(Elastic)
七、常见坑位
- 忘了
_score
:没写METADATA _score
+SORT _score DESC
时,哪怕用了MATCH
/QSTR
,也只是在过滤。(Elastic) - 多值字段:ES|QL 的搜索函数天然支持多值字段(如 tags 列表),比早期的“按 keyword 过滤”更合适。(Elastic)
- 语义召回期望过高:
semantic_text
默认行为很强,但质量仍依赖底层模型与数据域;必要时结合混合检索稳住查全率。(Elastic)
如果你给出当前索引 mapping(尤其是文本字段与是否要做语义),我可以按你的业务场景,直接产出可执行的 ES|QL 查询模板(过滤+搜索+排序+混合权重)以及一套AB 对比的评估指标方案。