在弹性搜索中操纵得分

时间:2015-12-29 09:17:03

标签: elasticsearch tags solr-boost

我想操纵我在搜索弹性搜索时得到的分数。 我已经使用了boost选项,但它没有给我我想要的结果。经过一番阅读后,我认为function_score查询是我问题的解决方案。 我理解它是如何工作的,但我无法弄清楚如何更改当前查询以将其与function_score查询一起使用。

"query": {
"filtered": {
    "query": {
        "bool": {
            "should": [{
                "multi_match": {
                    "type": "most_fields",
                    "query": "paus",
                    "operator": "and",
                    "boost": 2,
                    "fields": [
                        "fullname^2",
                        "fullname.folded",
                        "alias^2",
                        "name^2"
                    ],
                    "fuzziness": 0
                }
            }, {
                "multi_match": {
                    "type": "most_fields",
                    "query": "paus",
                    "operator": "and",
                    "boost": 1.9,
                    "fields": [
                        "taggings.tag.name^1.9",
                        "function",
                        "relations.master.name^1.9",
                        "relations.master.first_name^1.9",
                        "relations.master.last_name^1.9",
                        "relations.slave.name^1.9",
                        "relations.slave.first_name^1.9",
                        "relations.slave.last_name^1.9"
                    ],
                    "fuzziness": 0
                }
            }, {
                "multi_match": {
                    "type": "most_fields",
                    "query": "paus",
                    "operator": "and",
                    "fields": [
                        "fullname",
                        "alias",
                        "name"
                    ],
                    "boost": 0.2,
                    "fuzziness": 1
                }
            }, {
                "match": {
                    "extra": {
                        "query": "paus",
                        "fuzziness": 0,
                        "boost": 0.1
                    }
                }
            }]
        }
    },
    "filter": {
        "bool": {
            "must": [
                {
                    "terms": {
                        "type": ["Person"]
                    }
                },
                {
                    "term": {
                        "deleted": false
                    }
                }
            ]
        }
    }
}

正如您所看到的,我们有四种匹配。

  • 提升2:当名称上有完全匹配时
  • Boost 1.9:当标签上有完全匹配时
  • 提升0.2:当名称上有匹配但有一个字符写错时
  • 提升0.1:当额外(描述)字段中存在匹配时

我遇到的问题是,一个字符的匹配错误,没有标记得分高于带有正确标记的匹配和整个单词写错了。那应该是另一种方式......

任何帮助将不胜感激:)

1 个答案:

答案 0 :(得分:1)

对此没有明确的答案。您最好的朋友是Explain API,它会告诉您如何计算每个文档score

最重要的是要记住boost只是计算分数时考虑的因素之一。来自Docs

  

实际上,没有简单的公式来决定特定查询子句的“正确”提升值。这是一个尝试和看到的问题。请记住,提升是相关性得分中涉及的因素中的一个;它必须与其他因素竞争

如果您浏览TheoryLucene's Practical Scoring Function,这会对您有所帮助。这是Lucene使用的公式。

score(q,d)  =  
            queryNorm(q)  
          · coord(q,d)    
          · ∑ (           
                tf(t in d)   
              · idf(t)²      
              · t.getBoost() 
              · norm(t,d)    
            ) (t in q) 

现在,您未获得预期结果的几个原因之一可能是norm(t,d)idf(t)²。例如,如果你有extra字段作为 paus me 而其他字段有类似的东西,那么我的名字就是某些东西,这会给field length norm即价值norm(t.d)更高。此外,如果您在extra字段中说有10000个文档且只有一个文档具有 paus ,那么反向文档频率会非常高,因为它计算为{{ 1}}此处idf(t) = 1 + log ( numDocs / (docFreq + 1))numDocs=10000此值将被平方。我在我的数据集中遇到了这个问题。

模糊查询得分较高可能与this issue有关,基本上是Lucene Issue。这已在最新版本中修复。

可能有效的一种方法是让constant_score使用最后两个子句,然后将 5 提升为前两个子句。 This有助于理解。

尝试逐步解决此问题,从两个子句开始,查看docFreq=1的输出,然后尝试三个,最后全部四个。同时删除explain api并仅使用field boosting渐渐地你会明白的。

我希望这会有所帮助!!