Elasticsearch - 如何在组合常规查询和function_score时标准化得分?

时间:2014-08-18 11:03:36

标签: lucene elasticsearch search-engine

理想我想要实现的是为查询分配权重,使查询1占最终得分的30%,查询2构成其他70%,因此要获得最高分,文档必须在查询1和QUERY2。我对文档的研究没有提供任何关于如何实现这一点的提示,所以让我们尝试解决一个更简单的问题。

以下列形式考虑查询:

{
"query": {
    "bool": {
        "should": [
            {
                "function_score": {
                    "query": {"match_all": {}},
                    "script_score": {
                        "script": "<some_script>",
                    }
                }
            },
            {
                "match": {
                    "message": "this is a test"
                }
            }
        ]
    }
}
}

脚本可以返回任意数字(想想&gt;它可以返回类似12392002的内容)。

如何确保脚本的结果不会影响整体得分?

有没有办法将它标准化?例如,而不是脚本分数返回max_script_score的比率(由具有最高分数的文档实现)?

2 个答案:

答案 0 :(得分:9)

最近我正在研究这样的问题。我找不到关于这个问题的任何正式文档,但是当我使用“explain api”调查结果时,似乎“queryNorm”不适用于直接来自“functions”字段的分数。这意味着您无法直接规范化脚本值。

但是,我认为我发现这个问题有点棘手。如果将此函数字段与您执行的查询(match_all查询)结合使用并对该查询进行提升,则规范化正在对此查询进行处理,即这两个得分的乘法 - 从规范化查询和脚本 - 将给我们一个总归一化。为了更好的解释,查询将如下:

{
"query": {
    "bool": {
        "should": [
            {
                "function_score": {
                    "query": {"match_all": {"boost":1}},
                    "functions": [ {
                    "script_score": {
                        "script": "<some_script>",
                    }}],
                    "score_mode": "sum",
                    "boost_mode": "multiply"
                }
            },
            {
                "match": {
                    "message": "this is a test"
                }
            }
        ]
    }
}
}

这个答案不是你问题的正确解决方案,但我认为你可以使用这个查询来获得所需的结果。我给你的建议是使用explain api,尝试理解返回的内容,检查影响最终得分的参数,并使用脚本和提升值来获得优化的解决方案。

顺便说一下,“rescore query”可能有助于在最终得分上获得%30-%70比率:  Official documentation

答案 1 :(得分:0)

据我搜索,没有办法从弹性中获得归一化的分数。您将不得不通过进行两个查询来破解它。首先是一个试验查询(最好是大小为 1,但所有属性都相同),它将为您获取 max_score。然后你可以拍摄你的实际查询并使用functional_score来规范化分数。将您在 params 中作为试验查询的一部分获得的 max_score 传递给 function_score 并使用它来规范化每个分数。参考:This article snippet