使用嵌套查询将父doc _score与来自function_score的_score相乘

时间:2016-12-29 01:16:38

标签: elasticsearch

我想要的是获取与标题字段中的查询字词匹配的所有文档,如果查询字词也与嵌套字段完全匹配,则按嵌套对象中字段的值提升分数。

以下是我的示例文档:

{
  "Title": "The Heart of the Elastic Stack"
  "QueryClicks": [
      { "Term": "elastic stack", "Count": 100},
      { "Term": "elastic", "Count": 50},
      { "Term": "hard of the elastic", "Count": 200},
  ]
}

示例查询DSL:

{
  "query" : {
    "bool" : {
      "must" : [{
          "match" : {
            "Title" : "elastic stack"
          }
        }
      ],
      "should" : [{
          "nested" : {
            "path" : "QueryClicks",
            "query" : {
              "function_score" : {
                "query" : {
                  "match" : {
                    "QueryClicks.Term.lowercaseraw" : "elastic stack"
                  }
                },
                "functions" : [{
                    "script_score" : {
                      "script" : "log(doc['QueryClicks.Count'].value*4)"
                    }
                  }
                ],
                "boost_mode" : "replace"
              }
            }
          }
        }
      ]
    }
  }
}

对于某些queryterm,如果它与QueryClicks.Term中的一个匹配,它会以某种方式工作,额外的分数将被添加到文档的整个分数中。

但不完美,我想要的是将嵌套的函数得分(即log(doc [' QueryClicks.Count']。value * 4))乘以父文档' s以必须条款计算的分数。

如果我可以获得父文件的分数,那么我可以这样做:

"脚本":" log(doc [' QueryClicks.Count']。value * 4)* _parent_score"

但是,因为ES不支持从嵌套查询中获取父分数。还有其他方法吗?

目的是,将由QueryClicks.Count计算的_score和来自must query子句的_score相乘。

2 个答案:

答案 0 :(得分:0)

您已将boost_mode用作替换。这将忽略查询生成的分数。您当前的功能评分设置将仅使用score of function查询替换文档的分数。

要将函数查询的得分和查询生成的得分相乘,请使用以下查询

{
    "query": {
        "bool": {
            "must": [{
                "match": {
                    "Title": "elastic stack"
                }
            }],
            "should": [{
                "nested": {
                    "path": "QueryClicks",
                    "query": {
                        "function_score": {
                            "query": {
                                "match": {
                                    "QueryClicks.Term.lowercaseraw": "elastic stack"
                                }
                            },
                            "functions": [{
                                "script_score": {
                                    "script": "log(doc['QueryClicks.Count'].value*4)"
                                }
                            }],
                            "boost_mode": "multiply",
                            "score_mode": "sum"
                        }
                    }
                }
            }]
        }
    }
}

在这里,您可以相应地更换score_mode,以便评估函数内每个分数的功能分数。

希望这适合你。 感谢

答案 1 :(得分:0)

感谢。 我在之前的评论中没有清楚地回答你的问题。我试着解释更多细节。 你是对的,score_mode用于组合函数数组中所有函数的得分,而boost_mode用于将得分函数与查询得分结合起来。

我想要的是:

  1. 将父文档的分数与嵌套文档的分数相乘。
  2. 父级文件分数来自必须中的 {匹配:{"标题":"弹性堆栈"}} 子句。
  3. 嵌套的doc分数由嵌套的doc字段QueryClicks.Count计算,该字段包含在 should 子句的嵌套查询中的function_score中。
  4. 所以,在我的原始查询DSL中,我将boost_mode设置为"替换" ,因为我想要的分数应该子句实际上是分数来自以下脚本:

    "script": "log(doc['QueryClicks.Count'].value*4)"
    

    但由于它位于 should 子句中,因此会将其添加到必须子句的分数中。正如我所说,我希望它从必须子句中得分。

    如果将" boost_mode" 更改为"乘以"如您所建议,脚本分数将乘以嵌套匹配的分数: "匹配":{" QueryClicks.Term.lowercaseraw":"弹性堆栈"}

    关联查询("匹配":{" QueryClicks.Term.lowercaseraw":"弹性堆栈"} )上面的script_score只是使用脚本得分的前提条件。

    然后,此分数将添加到必须子句的分数中。这不是我想要的。

    希望这有助于您理解我的要求。