You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在OpenSearch/ElasticSearch中结合BM25与余弦相似度实现双评分查询

OpenSearch 双评分(BM25+余弦相似度)查询实现方案

需求实现思路

要先通过关键词筛选文档,再同时获取每个文档的BM25分数和向量余弦相似度分数,核心是保留原始BM25评分的同时,额外计算并返回余弦相似度分数。你之前用script_score会直接替换掉原始的BM25评分,所以无法同时拿到两个独立分数,改用以下两种方式即可实现:

方式一:仅筛选+返回双独立分数

这种方式先执行关键词筛选,再给每个返回文档附加BM25分数和余弦相似度分数,最终排序基于默认的BM25评分:

{
  "size": 10,
  "query": {
    "query_string": {
      "query": "Redox AND Battery OR (Fuel Cell)",
      "default_field": "*"
    }
  },
  "script_fields": {
    "bm25_score": {
      "script": {
        "source": "_score"
      }
    },
    "cosine_similarity_score": {
      "script": {
        "source": "cosineSimilarity(params.query_value, doc[params.field])",
        "params": {
          "field": "vector",
          "query_value": [0.1, 0.2, 0.3, ...] // 替换为你的实际查询向量
        }
      }
    }
  },
  "_source": true // 可选,设为false则仅返回分数,不返回原始文档内容
}
  • 外层query是你的必填关键词筛选逻辑,OpenSearch会自动用BM25算法计算文档的原始评分_score
  • script_fields用于额外计算并返回两个自定义字段:
    • bm25_score直接读取默认的_score,即BM25的计算结果
    • cosine_similarity_score通过脚本计算查询向量与文档向量的余弦相似度

方式二:筛选+双分数+自定义排序

如果需要基于BM25和余弦相似度的组合结果排序,同时保留两个独立分数,可用function_score实现:

{
  "size": 10,
  "query": {
    "function_score": {
      "query": {
        "query_string": {
          "query": "Redox AND Battery OR (Fuel Cell)",
          "default_field": "*"
        }
      },
      "functions": [
        {
          "script_score": {
            "script": {
              "source": "cosineSimilarity(params.query_value, doc[params.field])",
              "params": {
                "field": "vector",
                "query_value": [0.1, 0.2, 0.3, ...] // 替换为你的实际查询向量
              }
            }
          }
        }
      ],
      "score_mode": "sum", // 可选:multiply(相乘)、avg(平均)等,控制双分数的组合方式
      "boost_mode": "sum" // 控制原始BM25分数与组合分数的结合方式
    }
  },
  "script_fields": {
    "original_bm25_score": {
      "script": {
        "source": "_score"
      }
    },
    "cosine_similarity_score": {
      "script": {
        "source": "cosineSimilarity(params.query_value, doc[params.field])",
        "params": {
          "field": "vector",
          "query_value": [0.1, 0.2, 0.3, ...] // 替换为你的实际查询向量
        }
      }
    }
  }
}
  • function_score允许在原始BM25评分基础上,加入自定义评分函数(这里是余弦相似度)
  • score_mode和boost_mode可按需调整,比如sum会将BM25分数和余弦相似度分数相加作为最终排序分
  • 同样通过script_fields保留两个独立分数的返回

关键说明

  • script_score会完全覆盖原始的BM25评分,这是你之前无法同时获取两个分数的核心原因
  • 上述两种方式都能实现「布尔查询筛选→计算双独立分数」的流程,可根据是否需要自定义排序选择对应方案

内容的提问来源于stack exchange,提问作者Jake Winter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 01:10:29