当用户搜索 “quick pets” 时会发生什么呢?在前面的例子中,两个文档都包含词 quick
,但是只有文档 2 包含词 pets
,两个文档中都不具有同时包含 两个词 的 相同字段 。
如下,一个简单的 dis_max
查询会采用单个最佳匹配字段,而忽略其他的匹配:
{
"query": {
"dis_max": {
"queries": [
{ "match": { "title": "Quick pets" }},
{ "match": { "body": "Quick pets" }}
]
}
}
}
{
"hits": [
{
"_id": "1",
"_score": 0.12713557,
"_source": {
"title": "Quick brown rabbits",
"body": "Brown rabbits are commonly seen."
}
},
{
"_id": "2",
"_score": 0.12713557,
"_source": {
"title": "Keeping pets healthy",
"body": "My quick brown fox eats rabbits on a regular basis."
}
}
]
}
我们可能期望同时匹配 title
和 body
字段的文档比只与一个字段匹配的文档的相关度更高,但事实并非如此,因为 dis_max
查询只会简单地使用 单个 最佳匹配语句的评分 _score
作为整体评分。
tie_breaker 参数
可以通过指定 tie_breaker
这个参数将其他匹配语句的评分也考虑其中:
{
"query": {
"dis_max": {
"queries": [
{ "match": { "title": "Quick pets" }},
{ "match": { "body": "Quick pets" }}
],
"tie_breaker": 0.3
}
}
}
结果如下:
{
"hits": [
{
"_id": "2",
"_score": 0.14757764,
"_source": {
"title": "Keeping pets healthy",
"body": "My quick brown fox eats rabbits on a regular basis."
}
},
{
"_id": "1",
"_score": 0.124275915,
"_source": {
"title": "Quick brown rabbits",
"body": "Brown rabbits are commonly seen."
}
}
]
}
tie_breaker
参数提供了一种 dis_max
和 bool
之间的折中选择,它的评分方式如下:
- 获得最佳匹配语句的评分
_score
。 - 将其他匹配语句的评分结果与
tie_breaker
相乘。 - 对以上评分求和并规范化。
有了 tie_breaker
,会考虑所有匹配语句,但最佳匹配语句依然占最终结果里的很大一部分。
tie_breaker
可以是 0
到 1
之间的浮点数,其中 0
代表使用 dis_max
最佳匹配语句的普通逻辑, 1
表示所有匹配语句同等重要。最佳的精确值需要根据数据与查询调试得出,但是合理值应该与零接近(处于 0.1 - 0.4
之间),这样就不会颠覆 dis_max
最佳匹配性质的根本。