我试图解决我们在查询ElasticSearch几千个结果时遇到的性能问题。基本思想是我们进行一些查询后处理,只显示前X个结果(查询可能有~100000个结果,而根据我们的分数机制我们只需要前100个。)
基本机制如下: ElasticSearch得分在0..1(得分/最高(得分))之间归一化,我们将我们的排名得分(也在0..1之间归一化)除以2。
我想做的是使用自定义评分(或者任何有效的方法)将此逻辑移至ElasticSearch:https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html#function-script-score
我面临的问题是使用分数脚本/分数函数我似乎找不到像max(_score)那样的方法来将分数归一化到0到1之间。
"script_score" : {
"script" : "(_score / max(_score) + doc['some_normalized_field'].value)/2"
}
欢迎任何想法。
答案 0 :(得分:2)
在为所有匹配的文档实际生成 _score 之前,您无法获得 max_score 。 script_score 查询将首先为所有匹配的文档生成 _score ,然后 max_score 将由elasticsearch显示。
根据我对您的问题的了解,在应用“ script_score”之前,您想保留由原始查询生成的 max_score 。如果在前端进行一些计算,则可以获得所需的结果。简而言之,将您的公式应用于前端,然后对结果进行排序。
您可以使用script_fields查询将因子保存在结果中。
{
"explain": true,
"query": {
"match_all": {}
},
"script_fields": {
"total_goals": {
"script": {
"lang": "painless",
"source": """
int total = 0;
for (int i = 0; i < doc['goals'].length; ++i) {
total += doc['goals'][i];
}
return total;
""",
"params":{
"last" : "any parameters required"
}
}
}
}
}
答案 1 :(得分:0)
我不确定我理解你的问题。你想限制结果数量吗?
你尝试过吗?{
"from" : 0, "size" : 10,
"query" : {
"term" : { "name" : "dennis" }
}
}
您可以使用排序来定义排序顺序,默认情况下它将按主查询排序。
你也可以使用聚合(有或没有function_score)
{
"query": {
"function_score": {
"functions": [
{
"gauss": {
"date": {
"scale": "3d",
"offset": "7d",
"decay": 0.1
}
}
},
{
"gauss": {
"priority": {
"origin": "0",
"scale": "100"
}
}
}
],
"query": {
"match" : { "body" : "dennis" }
}
}
},
"aggs": {
"hits": {
"top_hits": {
"size": 10
}
}
}
}
答案 2 :(得分:0)
基于此github ticket,完全不可能归一化分数,他们建议使用boolean similarity作为解决方法。