Elasticsearch如何计算此功能分数查询中的分数?奇怪的行为

时间:2019-01-14 17:33:36

标签: elasticsearch

我正在使用script_score基于字段的值来计算分数,我们称其为likeability类型的float

脚本为:

_score * (1 + _doc['likeability'].value)

除了likeability和ID以外,我还有一些相同的文档。

当我按如下所示运行功能分数查询时,得到以下结果:

id | likeability | score
A  | 3.5         | 56.961056
B  | 2.0         | 37.974037
C  | 1.5         | 31.645031
D  | 0.5         | 18.987019
E  | 1.0         | 16.044298
F  | 0.0         |  8.022149 

具有0.5相似度的文档D的得分高于具有1.0相似度的E的得分。

有人知道为什么会这样吗?

我的机器上有这个问题,它消失了。但是现在发生在另一台机器上。

这与分片数量有关吗?

这是我的查询:

{
  "from": 0,
  "size": 50,
  "query": {
    "function_score": {
      "query": { ... }
      },
      "functions": [
        {
          "filter": {
            "match_all": {
              "boost": 1.0
            }
          },
          "script_score": {
            "script": {
              "inline": "_score * (1 + doc['likeability'].value)",
              "lang": "painless"
            }
          }
        }
      ],
      "score_mode": "multiply",
      "boost_mode" : "replace",
      "max_boost": 3.4028235E+38,
      "boost": 1.0
    }
  }
}

编辑:

我再次仔细检查了一下,看来它可能需要对碎片进行某些处理,因为如果我从脚本中计算出_score,那么它就有两个值:

id | likeability | score

_score of 12,65777
A  | 3.5         | 56.961056
B  | 2.0         | 37.974037 
C  | 1.5         | 31.645031 
D  | 0.5         | 18.987019 

_score of 8.022149
E  | 1.0         | 16.044298 
F  | 0.0         |  8.022149

1 个答案:

答案 0 :(得分:0)

正如评论中所讨论的,问题归结为碎片太多和数据太少。该问题在https://www.elastic.co/guide/en/elasticsearch/guide/current/relevance-is-broken.html中进行了详细说明,但总的来说,问题是TF / IDF的IDF部分。它可以统计所有术语(在一个字段中)在一个文档中的通用性。稀有术语更“有价值”,并且得分更高。但是,与直觉相反,此统计信息是按碎片计算的。如果您的数据分布不均,您的分数将会下降。

还可以选择?search_type=dfs_query_then_fetch来计算总体统计信息,但这并不是必须的。您要么拥有足够的数据都无关紧要,要么应该使用单个分片。