OpenSearch中使用评分脚本时如何获取纯k-NN分数及实现排序需求
OpenSearch脚本评分结合精确k-NN的问题解答
1. 当前分数的计算方式
你使用的script_score查询逻辑是:先通过bool filter完成预过滤(这里是price范围筛选),再对每个符合条件的文档执行knn_score脚本计算最终得分。
针对cosinesimil(余弦相似度)类型的k-NN分数,OpenSearch内部会先算出查询向量与文档向量的余弦相似度值(范围是**[-1, 1]**),为了适配评分体系的正分需求,会自动做转换:最终得分 = 余弦相似度值 + 1。
2. 分数为何超过1?
余弦相似度的最大值是1,加上1之后会得到0到2之间的正数。你看到的1.017859,对应的原始余弦相似度是0.017859,转换后自然超过了1。
3. 预过滤后能否仅获取k-NN的相似度分数?
可以,只需修改knn_score脚本的计算逻辑,直接返回原始的余弦相似度值即可。
4. 预过滤后仅基于k-NN分数排序的实现方法
有两种简洁的实现方式:
方式一:修改脚本返回原始相似度并排序
直接用cosineSimilarity函数计算原始余弦相似度,让得分直接作为排序依据:
GET /my_index/_search { "query": { "script_score": { "query": { "bool": { "filter": { "range": { "price": { "gte": 200, "lte": 350 } } } } }, "script": { "source": "cosineSimilarity(params.query_value, doc[params.field])", "params": { "field": "my_vector", "query_value": [1.5, 5.5, 4.5, 6.4] } } } }, "sort": [ { "_score": { "order": "desc" } } ] }
这里得分范围是[-1,1],按降序排列后,相似度越高的文档越靠前。
方式二:用function_score替代script_score
通过filter完成预过滤,再用script_score函数返回原始相似度,并用boost_mode: replace确保最终得分完全由k-NN相似度决定:
GET /my_index/_search { "query": { "function_score": { "filter": { "range": { "price": { "gte": 200, "lte": 350 } } }, "functions": [ { "script_score": { "script": { "source": "cosineSimilarity(params.query_value, doc[params.field])", "params": { "field": "my_vector", "query_value": [1.5, 5.5, 4.5, 6.4] } } } } ], "boost_mode": "replace" } }, "sort": [ { "_score": { "order": "desc" } } ] }
内容的提问来源于stack exchange,提问作者Gengis Khan
相关产品推荐
相关产品推荐

