mcpField
E
elasticsearch-search-relevance

elasticsearch-search-relevance

github.com/elastic数据与数据库6021.1k 次安装今天更新
代码仓库

关于 elasticsearch-search-relevance

此技能通过 elastic CLI 调整 Elasticsearch 全文搜索相关性,适用于维护内容或商品索引的人员。它根据映射选择查询规则置顶或多字段查询调优,并比较调整前后的结果。

主要功能

  1. 01检查索引映射与当前查询
  2. 02用查询规则置顶或排除文档
  3. 03通过多字段查询调整自然排序
  4. 04比较调整前后的搜索结果
  5. 05通过 elastic CLI 执行操作

适用场景

  1. 01让指定商品在特定查询中排第一
  2. 02提升标题与描述中的相关结果
  3. 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 或排序子句来模拟置顶。

流程

  1. 检查映射和当前查询。 调用 GET / 确认连接正常。如果索引未知,先通过 GET /_cat/indices 缩小候选范围,再调用 GET /{index}/_mapping。

    根据映射列出所有 text 字段(例如 title、description)以及用于筛选的所有 keyword 字段(brand、category)。注明哪些字段较短(精确率高),哪些字段较长(召回率高)。如果用户提供了当前搜索请求体,请阅读并确认它查询了哪些字段,以及是否已使用 rule、multi_match 或单字段 match。

    决策: 问题属于确定性提升(某个文档必须在某个查询中胜出),还是自然排序(多个文档的得分应有所提升)?所需数据: 索引名称、映射属性、当前查询 JSON、示例查询字符串,以及置顶时的目标文档 ID。

  2. 选择相关性杠杆。 应用步骤 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 名称、条件元数据键,以及置顶文档标识符。

  3. 应用更改。 执行所选杠杆对应的 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 检查分析结果。

    决策: 完成一组连贯的更改后即停止;测试前避免叠加无关修改。

  4. 测试并比较排名靠前的命中结果。 对每个候选方案进行前后对比时,调用 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 搜索查询。

正确:

  1. 使用类型为 pinned 的规则调用 PUT /_query_rules/catalog-sale-pin,设置匹配查询文本 "sale" 的条件,并在操作中置顶 SKU123。
  2. 调用 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 查询。

正确做法:

  1. 基准:使用用户当前对 description 的 match 查询执行 POST /catalog/_search;记录排名靠前的命中结果。
  2. 候选方案:使用以下查询执行 POST /catalog/_search:
{
  "query": {
    "multi_match": {
      "query": "running shoes",
      "fields": ["title^2", "description"],
      "type": "best_fields",
      "operator": "or",
      "minimum_should_match": "75%"
    }
  },
  "size": 10
}
  1. 比较排名靠前的命中结果——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/indiceselastic es cat indices --index '<pattern>'
GET /{index}/_mappingelastic 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}/_testelastic es query-rules test --ruleset-id '<id>' --match-criteria '<json>'
POST /{index}/_searchelastic es search --index '<index>' --query '<json>'
POST /{index}/_analyzeelastic es indices analyze --index '<index>' --field '<field>' --text '<text>'

评论

支持 Markdown