【问题标题】:Elasticsearch FunctionScore Query ScoreMode isn't working as expectedElasticsearch FunctionScore Query ScoreMode 未按预期工作
【发布时间】:2016-05-13 18:53:41
【问题描述】:

我们有一个包含大约 50 个函数的函数分数查询。每个函数都有一个过滤器和一个 script_score。我们将分数模式指定为 SUM。

映射:

 "keywords": {
        "type": "nested",
        "include_in_parent": true,
        "properties": {
          "id": {
            "type": "string",
            "index_name": "id",
            "analyzer": "standard"
          },
          "name": {
            "type": "string",
            "index_name": "name"
          },
          "score": {
            "type": "double",
            "index_name": "keywordScore"
          }
        }
      }

示例查询:

 {
  "query": {
    "bool": {
      "should": {
        "nested": {
          "query": {
            "function_score": {
              "functions": [
                {
                  "filter": {
                    "term": {
                      "keywords.id": "np14y9393"
                    }
                  },
                  "script_score": {
                    "script": {
                      "inline": "(doc['keyword.score'].value*log(0.138317))+100"
                    }
                  }
                },
                {
                  "filter": {
                    "term": {
                      "keywords.id": "ny6579591"
                    }
                  },
                  "script_score": {
                    "script": {
                      "inline": "(doc['keyword.score'].value*log(0.0631535))+100"
                    }
                  }
                }
              ],
              "score_mode": "sum",
              "boost_mode": "sum"
            }
          },
          "path": "keywords"
        }
      }
    }
  }
}

问题:

  1. 每个 script_score 中的公式处理从 0 到 1 的概率。因此 script_score 的输出将始终小于 1。例如:0.00456。在这种情况下,Elasticsearch 会忽略来自 script_score 的分数。我在我的脚本中添加了 100,它返回 100.00456。在这种情况下,分数会显示在最终分数中。可能是 Elasticsearch 具有一定的截止精度,因此它的行为方式是这样的。

  2. 尽管 SUM 被指定为分数模式,但 Elasticsearch 在内部对该分数进行了一些平均。正如我之前所说,我将在查询中包含 50 个函数。如果匹配了10个关键词,那么得分应该在1000左右。但是结果得分在80左右。那么这个得分模式是如何使用的呢?如何告诉 Elasticsearch 不要标准化分数并使用我指定的分数?

  3. Explain API 在这里用处不大。它并没有说明每个功能级别的分数是多少以及它是如何操纵的。

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    假设您的索引中有一组 5 个文档,当您运行查询时,它应该在每个文档上一个接一个地运行。让我们在第一个被索引的文档上空运行查询。

    第一个文档的最终 _score 将是:

    _score = es_score ([0-1]) + function_score;
    

    es_score 介于 0 到 1 之间。

    考虑到您的所有 50 个函数都基于 keywords.id filterscript_score,每个函数几乎相同,并假设匹配的函数过滤器数量为 x

    _score = es_score + function_score(func1) + .... + function_score(funcx);
    _score = es_score + [(doc['keyword.score'].value*log(0.138317))+100] + .... + [(doc['keyword.score'].value*log(0.138317))+100];
    
    _score = es_score + [-value1 + 100] + .... + [-valueX + 100];
    

    因此,这取决于您的计算日志的值(可能是负整数),以及文档的 _score 值。

    【讨论】:

    • 同意值可以是负数。但是如果匹配了10个函数过滤器,由于score_more是SUM,所以function_score应该是10*98(appx) = 980。所以_score=es_score+980,应该大于980。但是结果分数总是小于100. 这意味着 Elasticsearch 正在对 function_score 结果进行某种标准化。我的问题是如何告诉 Elasticsearch 不要那样做。
    • keyword.score 的值是否在特定范围内?这取决于keyword.score 的值,总计算值可以是多少。
    • 是的。它是一个介于 0 到 1 之间的概率值
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-04
    • 2019-05-24
    • 2019-10-24
    • 2018-09-15
    • 2019-04-18
    • 1970-01-01
    相关资源
    最近更新 更多