关于 elasticsearch-search-relevance
此技能通过 elastic CLI 调整 Elasticsearch 全文搜索相关性,适用于维护内容或商品索引的人员。它根据映射选择查询规则置顶或多字段查询调优,并比较调整前后的结果。
主要功能
- 01检查索引映射与当前查询
- 02用查询规则置顶或排除文档
- 03通过多字段查询调整自然排序
- 04比较调整前后的搜索结果
- 05通过 elastic CLI 执行操作
适用场景
- 01让指定商品在特定查询中排第一
- 02提升标题与描述中的相关结果
- 03排查多词查询的召回问题
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ elastic/ agent-skills --skill elasticsearch-search-relevance安装后在 Claude Code 中输入/elasticsearch-search-relevance确认已加载。
附带文件references/multi-match-tuning.mdreferences/query-rules-reference.md
详细介绍
Elasticsearch 搜索相关性
提升内容和目录索引的全文搜索结果。诊断映射和当前查询,选择合适的相关性调节方式(用于确定性置顶的查询规则,或用于自然排序的 multi_match 和字段权重),应用更改,并在报告成功前验证排名靠前的命中结果。
环境配置
此技能通过 elastic CLI 执行 Elasticsearch 操作。如果未安装 elastic CLI,请告知用户安装它的必要性。不要猜测凭据、直接调用 HTTP API,也不要尝试其他变通方法。
此技能以 HTTP 简写形式引用操作(例如,GET /、GET /_cat/indices、GET /{index}/_mapping、GET /{index}/_settings/index.mode、POST /_query)。本文末尾的 操作 表将每种简写映射到对应的 elastic CLI 命令——始终使用 CLI,不要直接调用 HTTP API。
范围
此技能涵盖索引中基于 text(以及可选的 keyword)字段的 Query DSL 相关性——产品目录、文档、知识库。它使用 POST /{index}/_search 进行评估,并使用查询规则 API 固定或排除文档。
不在范围内:
- ES|QL 搜索(
POST /_query)——请使用elasticsearch-esql技能。 - 语义 / 向量 / 混合检索——使用不同的字段类型和检索器。
- 取代修正文本相关性,改为按价格、日期或热度排序,除非用户明确要求按相关性之外的方式排序。
相关性调节方式
| 用户意图 | 调节方式 | API |
|---|---|---|
| 对查询 Q 始终将文档 X 显示在首位 | 查询规则——pinned 规则 + 搜索中的 rule 查询 | PUT /_query_rules/{ruleset_id}、POST /{index}/_search |
| 对查询 Q 隐藏特定文档 | 查询规则——exclude 规则 + rule 查询 | 同上 |
| 提升开放式文本查询的排序 | 在映射的 text 字段中使用 multi_match,并设置字段权重 | POST /{index}/_search |
| 分词与用户语言不匹配 | 运算符、minimum_should_match 或同义词分析器 | POST /{index}/_search,可选 POST /{index}/_analyze |
决策规则: 如果用户指定某个文档,要求它在特定查询中必须排在首位,请使用查询规则。如果某个短语的搜索结果整体较差,请根据映射调整自然排序查询。不要使用极端权重、function_score 或排序子句来模拟置顶。
流程
-
检查映射和当前查询。 调用
GET /确认连接正常。如果索引未知,先通过GET /_cat/indices缩小候选范围,再调用GET /{index}/_mapping。根据映射列出所有
text字段(例如title、description)以及用于筛选的所有keyword字段(brand、category)。注明哪些字段较短(精确率高),哪些字段较长(召回率高)。如果用户提供了当前搜索请求体,请阅读并确认它查询了哪些字段,以及是否已使用rule、multi_match或单字段match。决策: 问题属于确定性提升(某个文档必须在某个查询中胜出),还是自然排序(多个文档的得分应有所提升)?所需数据: 索引名称、映射属性、当前查询 JSON、示例查询字符串,以及置顶时的目标文档 ID。
-
选择相关性杠杆。 应用步骤 1 中的决策:
-
置顶/推广 → 创建一个 query-rules 规则集,并添加类型为
pinned的规则(推广时绝不要使用exclude)。设置criteria,使规则仅在目标查询文本下触发——例如,对query_string之类的元数据键使用contains或exact,值为"sale"。设置actions,通过ids(例如,["SKU123"])或docs(例如,[{"_index":"catalog","_id":"SKU123"}])置顶正确的文档。当_id在不同索引中可能不唯一时,使用docs。完整结构请参阅查询规则参考。 -
自然排名 → 将长字段上的单字段
match替换为跨已映射text字段的multi_match。提高短字段的权重(通常是title^2,而description不提高权重)。如果多词召回仍然较差,可考虑使用operator、minimum_should_match或支持同义词的分析器——但不要按价格、日期或 keyword 字段排序来伪造更好的文本相关性,也不要对经过分析的用户短语使用term查询.keyword子字段。请参阅 Multi-Match 调优。
决策: 每个请求只选择一个主要杠杆。所需数据: 选定的字段和权重、规则集 ID 和规则 ID 名称、条件元数据键,以及置顶文档标识符。
-
-
应用更改。 执行所选杠杆对应的 API:
查询规则路径
- 使用
PUT /_query_rules/{ruleset_id}创建或替换规则集(或使用PUT /_query_rules/{ruleset_id}/_rule/{rule_id}添加一条规则)。 - 使用
GET /_query_rules/{ruleset_id}确认结构。 - 使用
POST /_query_rules/{ruleset_id}/_test,并传入与搜索时相同的match_criteria,验证条件。 - 接入搜索:
POST /{index}/_search必须使用rule查询,其ruleset_id引用该规则集,并且其match_criteria为每个条件metadata键提供值(例如,"query_string": "sale")。将常规相关性子句放在organic中。仅创建规则集不会置顶任何内容——只有搜索包含rule查询时才会应用置顶规则。
自然排名调优路径
- 根据映射构建候选
multi_match(或等效的 bool/should)查询。 - 如果分词方式可以解释未命中,可选用示例查询文本调用
POST /{index}/_analyze检查分析结果。
决策: 完成一组连贯的更改后即停止;测试前避免叠加无关修改。
- 使用
-
测试并比较排名靠前的命中结果。 对每个候选方案进行前后对比时,调用
POST /{index}/_search,使用相同的size(≥ 10)、用户查询字符串和"track_scores": true。对于置顶,搜索请求体必须包含步骤 3 中的rule查询。每次运行都比较:
- 排名靠前的
_id值及其顺序 - 相关的
_score - 关键
_source字段(title、description、产品 ID)
对于置顶,确认当
match_criteria与查询匹配时,目标文档(例如,SKU123)位于第一位,且其下方仍显示自然匹配结果。对于自然排名调优,确认标题和符合用户意图的文档排名上升,且不依赖排序或关键词精确匹配技巧。决策: 根据证据发布表现最佳的候选方案;如果没有方案能改善结果,请报告已尝试的内容并提出下一种杠杆(例如,同义词或其他字段)。所需数据: 基线查询和候选查询的排名靠前命中列表对照。
- 排名靠前的
示例
为 catalog 中的查询 "sale" 置顶 SKU123
错误: 提高 SKU123 的权重、按 _id 排序,或创建规则集但不使用 rule 搜索查询。
正确:
- 使用类型为
pinned的规则调用PUT /_query_rules/catalog-sale-pin,设置匹配查询文本"sale"的条件,并在操作中置顶SKU123。 - 调用
POST /catalog/_search,请求体如下:
{
"query": {
"rule": {
"ruleset_id": "catalog-sale-pin",
"match_criteria": { "query_string": "sale" },
"organic": {
"multi_match": {
"query": "sale",
"fields": ["title^2", "description"]
}
}
}
},
"size": 10
}
确认 SKU123 是第 #1 个命中结果,其余命中结果作为自然匹配显示在置顶项下方。
仅搜索 description 时,提升“running shoes”的搜索效果
映射将 title 和 description 定义为 text,将 brand 和 category 定义为 keyword。
错误做法: 仅对 description 使用 match;按价格排序;对 title.keyword 使用 term 查询。
正确做法:
- 基准:使用用户当前对
description的match查询执行POST /catalog/_search;记录排名靠前的命中结果。 - 候选方案:使用以下查询执行
POST /catalog/_search:
{
"query": {
"multi_match": {
"query": "running shoes",
"fields": ["title^2", "description"],
"type": "best_fields",
"operator": "or",
"minimum_should_match": "75%"
}
},
"size": 10
}
- 比较排名靠前的命中结果——
title中包含“running shoes”的文档应排在仅在描述中匹配的结果之前。如果召回率仍然偏低,可在后续迭代中考虑扩展同义词(而不是按价格排序)。
指南
- 所有字段名都必须以映射为依据——先检查
GET /{index}/_mapping,切勿凭空编造name、content或body。 - 置顶使用查询规则,排名使用加权——商品推广应使用查询规则;字段加权应放在自然查询中。
- 必须正确配置匹配条件——规则条件中的
metadata键必须出现在搜索的rule.match_criteria对象中,并使用运行时的值(通常是用户的查询字符串)。 - 先测试,再声称成功——运行基准查询和候选查询,并说明排名靠前的命中结果有哪些变化。
keyword字段用于过滤,text字段用于搜索——在filter上下文中使用keyword字段,不要将其作为自然语言全文搜索的主要目标。- 始终交付具体产物——即使无法连接集群进行验证,也要提供完整的规则集 JSON(用于置顶)或候选查询正文(用于自然搜索调优),然后说明连接可用后如何验证。不要止步于高层概述。
参考资料
操作
| HTTP API(简写) | elastic CLI 命令 |
|---|---|
GET / | elastic es info |
GET /_cat/indices | elastic es cat indices --index '<pattern>' |
GET /{index}/_mapping | elastic es indices get-mapping --index '<index>' |
PUT /_query_rules/{ruleset_id} | elastic es query-rules put-ruleset --ruleset-id '<id>' --rules '<json>' |
PUT /_query_rules/{ruleset_id}/_rule/{rule_id} | elastic es query-rules put-rule --ruleset-id '<id>' --rule-id '<id>' --type pinned --criteria '<json>' --actions '<json>' |
GET /_query_rules/{ruleset_id} | elastic es query-rules get-ruleset --ruleset-id '<id>' |
POST /_query_rules/{ruleset_id}/_test | elastic es query-rules test --ruleset-id '<id>' --match-criteria '<json>' |
POST /{index}/_search | elastic es search --index '<index>' --query '<json>' |
POST /{index}/_analyze | elastic es indices analyze --index '<index>' --field '<field>' --text '<text>' |