【问题标题】:What is the reasoning behind the ranking of this ElasticSearch query?这个 ElasticSearch 查询排名背后的原因是什么?
【发布时间】:2013-03-29 07:26:24
【问题描述】:

我有两个文件:

{
    id: 7,
    title: 'Wet',
    description: 'asdfasdfasdf'
}

{
    id: 6
    title: 'Wet wet',
    description: 'asdfasdfasdf'
}

除了第二个文档中的多余单词之外,它们几乎相同。

我的查询是这样的:

var qobject = {
        query:{
            custom_score:{
                query:{
                   multi_match:{
                     query: q, //I searched for "wet"
                     fields: ['title','description'],
                   }
                },
                script: '_score '
            }
        }
    }

好的,所以当我运行这个查询时,我会得到以下结果:

{ total: 2,
  max_score: 1.8472979,
  hits: 
   [ { _index: 'products',
       _type: 'products',
       _id: '7',
       _score: 1.9808292,
       _source: [Object] },
     { _index: 'products',
       _type: 'products',
       _id: '6',
       _score:  1.7508222,
       _source: [Object] } ] }

为什么 id 7 的排名高于 id 6?得分背后的原因是什么? 6不应该因为有2个词而排名更高吗?

如果我想要更多的单词 = 更多的权重怎么办?我该如何修改我的查询?

解释如下:

"_explanation": {
            "value": 1.9808292,
            "description": "custom score, product of:",
            "details": [
                {
                    "value": 1.9808292,
                    "description": "script score function: composed of:",
                    "details": [
                        {
                            "value": 1.9808292,
                            "description": "fieldWeight(title:wet in 0), product of:",
                            "details": [
                                {
                                    "value": 1,
                                    "description": "tf(termFreq(title:wet)=1)"
                                },
                                {
                                    "value": 1.9808292,
                                    "description": "idf(docFreq=2, maxDocs=8)"
                                },
                                {
                                    "value": 1,
                                    "description": "fieldNorm(field=title, doc=0)"
                                }
                            ]
                        }
                    ]
                },
                {
                    "value": 1,
                    "description": "queryBoost"
                }
            ]
        }

"_explanation": {
            "value": 1.7508222,
            "description": "custom score, product of:",
            "details": [
                {
                    "value": 1.7508222,
                    "description": "script score function: composed of:",
                    "details": [
                        {
                            "value": 1.7508222,
                            "description": "fieldWeight(title:wet in 0), product of:",
                            "details": [
                                {
                                    "value": 1.4142135,
                                    "description": "tf(termFreq(title:wet)=2)"
                                },
                                {
                                    "value": 1.9808292,
                                    "description": "idf(docFreq=2, maxDocs=8)"
                                },
                                {
                                    "value": 0.625,
                                    "description": "fieldNorm(field=title, doc=0)"
                                }
                            ]
                        }
                    ]
                },
                {
                    "value": 1,
                    "description": "queryBoost"
                }
            ]
        }

【问题讨论】:

  • 请问您想通过自定义分数查询实现什么目标?此外,您错过了问题中最重要的一点:您正在搜索的字词。

标签: lucene indexing elasticsearch


【解决方案1】:

查看查询的解释输出以了解原因。您可以使用explain api 或将"explain": true 添加到您当前的搜索请求中。

默认情况下,lucene 使用 tf/idf(词频,倒置文档频率)相似度对文档进行评分。对于与查询匹配的每个术语,都会考虑不同的因素。以下是最重要的:

  • 词频:词在文档中出现的频率。越多越好。如果一个术语出现多次,则该文档是更好的匹配。
  • 倒排文档频率:该词在索引中的频率。越少越好。罕见术语胜过通用术语。
  • 规范:索引时间提升(默认为 1,无提升)+ 字段规范,它定义了较短的字段优于较长的字段。

根据您正在执行的查询,由于规范,文档的评分不同。您可以在映射(和重新索引)中禁用规范,但这样您也会失去索引时间提升(我认为您无论如何都不会使用它)。事实上,在您的示例中,第二个文档的得分较低,因为字段规范较低,尽管词频较高(2 而不是 1)。

另一个解决方案是插入不同的 lucene 相似性:lucene 4 提供了更多的相似性,并且还允许定义每个字段的相似性。这些功能已在 elasticsearch 0.90 中公开。

【讨论】:

  • 谢谢贾瓦娜。我已经编辑了我的问题以包括解释和我的查询(“湿”)。你能看看我的解释查询吗?最终分数是如何计算的……是在细节中取平均值吗?
  • 我猜两个词的文档比一个词的文档低的原因是:“value”:0.625,“description”:“fieldNorm(field=title,doc=0)” ...规范到底有什么好处?
  • 是的。第二个文档获得更高的 tf,因为它包含两次该术语,但另一方面,该字段的范数较低(0.625 而不是一个),这也会影响分数,甚至超过 tf.字段规范应类似于:1/sqrt(number of terms).
  • 您是否建议我关闭规范? (或者这只是一个坏例子?)
  • 好吧,您应该尝试使用更多真实数据,看看规范是否仍然困扰您。在这种情况下是的,您可以禁用它。那么字段的长度就不再重要了。
猜你喜欢
  • 1970-01-01
  • 2011-06-20
  • 1970-01-01
  • 1970-01-01
  • 2019-12-24
  • 2018-08-31
  • 2020-01-26
  • 2016-03-31
  • 2021-11-01
相关资源
最近更新 更多