ElasticSearch最高分数

时间:2016-01-18 17:14:38

标签: elasticsearch

我试图解决我们在查询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"
}

欢迎任何想法。

3 个答案:

答案 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作为解决方法。