我想操纵我在搜索弹性搜索时得到的分数。 我已经使用了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
}
}
]
}
}
}
正如您所看到的,我们有四种匹配。
我遇到的问题是,一个字符的匹配错误,没有标记得分高于带有正确标记的匹配和整个单词写错了。那应该是另一种方式......
任何帮助将不胜感激:)
答案 0 :(得分:1)
对此没有明确的答案。您最好的朋友是Explain API,它会告诉您如何计算每个文档score
。
最重要的是要记住boost
只是计算分数时考虑的因素之一。来自Docs
实际上,没有简单的公式来决定特定查询子句的“正确”提升值。这是一个尝试和看到的问题。请记住,提升是相关性得分中涉及的因素中的一个;它必须与其他因素竞争
如果您浏览Theory和Lucene'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
。 渐渐地你会明白的。
我希望这会有所帮助!!