ElasticSearch相关性异常疑问:-0.68为何变为0.13?
首先,咱们来拆解你遇到的问题:你预期score_mode: max会直接取function返回的-0.68作为最终得分,但实际得到了0.13,这背后主要有两个关键原因,还有对应的解决方法:
1. 为什么得分不是-0.68?
从你给出的评分详情来看,外层的function score, score mode [max]确实会对多个function的结果取最大值,但这里有个容易忽略的点:默认情况下,function score的结果会和原始查询的得分进行组合(默认是boost_mode: multiply,也就是相乘)。
你的详情里显示内部function的product结果是-0.68,但最终的0.13其实是这个值和原始查询得分相乘后的结果——比如如果原始查询的得分是-0.199左右,相乘后就会得到0.13左右的正数。而原始查询的得分之所以是这个数值,确实和query norms有关:它是Elasticsearch用来标准化不同查询得分的内置因子,会被自动乘到原始查询的得分上。
2. 如何覆盖这个行为?
根据你的需求,要让相关性函数持续使用你预期的数值,可以从这几个方面调整:
(1)让function得分完全替代原始得分
把boost_mode设置为replace,这样Elasticsearch就会直接使用function计算出的得分,而不会和原始查询得分进行组合。示例查询结构如下:
{ "query": { "function_score": { "query": { "match": { "brand": "brandy" } }, "functions": [ // 这里放你的function定义,比如script_score、weight等 ], "score_mode": "max", "boost_mode": "replace" // 关键设置:直接使用function得分 } } }
(2)消除query norms的影响
如果你想彻底去掉query norms对得分的影响,可以在目标字段的映射中设置"norms": false,这样该字段的查询就不会应用query norms标准化。注意这个设置需要重新索引数据,示例映射:
{ "mappings": { "properties": { "brand": { "type": "text", "norms": false // 关闭该字段的norms } } } }
(3)检查function的完整逻辑
你的评分详情被截断了(det...部分),建议确认内部的product模式是否还有其他未显示的function参与计算——比如是否有script返回了负数,或者其他weight因子,这也可能影响最终的function得分。
内容的提问来源于stack exchange,提问作者aclowkay

