如果一个查询包含在
function_score
查询中,则两个带引号短语的相同查询字符串查询的结果将返回不同的结果。在包装的查询中,该短语并未完整保留,而是被标记化,这可以通过突出显示的结果看到。
查询A:
GET consolidated-index991/_search
{
"from": 0,
"highlight": {
"fields": {
"content": {}
},
"max_analyzed_offset": 999999,
"number_of_fragments": 5
},
"query": {
"function_score": {
"query": {
"query_string": {
"analyzer": "cg_analyzer_naziv",
"fields": [
"content"
],
"query": "\"savo pejovic\"",
"boost": 3
}
}
}
},
"size": 10,
"sort": [
{
"_score": {
"order": "desc"
}
}
],
"_source": {
"includes": [
"genericReference",
"isActive"
]
}
}
查询B:
{
"from": 0,
"highlight": {
"fields": {
"content": {}
},
"max_analyzed_offset": 999999,
"number_of_fragments": 5
},
"query": {
"query_string": {
"analyzer": "cg_analyzer_naziv",
"fields": [
"content"
],
"query": "\"savo pejovic\"",
"boost": 3
}
},
"size": 10,
"sort": [
{
"_score": {
"order": "desc"
}
}
],
"_source": {
"includes": [
"genericReference",
"isActive"
]
}
}
QueryA 返回仅突出显示这些标记之一的命中,而 QueryB 仅返回具有突出显示的精确短语的命中。
如何使 QueryA 表现得像 QueryB?
当您直接使用 query_string 查询而不将其包装在 function_score 查询中时,将根据指定的分析器(本例中为 cg_analyzer_naziv)分析查询字符串,并处理整个带引号的短语 “savo pejovic”在分析过程中作为单个实体。这意味着该查询被视为短语查询,并且只有包含确切短语 “savo pejovic” 的文档才会匹配。
但是,当您将 query_string 查询包装在 function_score 查询中时,行为会发生变化。 function_score 查询允许您根据各种因素修改查询返回的文档的分数。在这种情况下,当您将 query_string 查询包装在 function_score 中时,仍使用指定的分析器 (cg_analyzer_naziv) 分析 query_string 查询,但评分会根据 function_score 查询中定义的规则进行修改。
在完全匹配的情况下,function_score查询可能会无意中破坏此行为。例如,如果您有一个基于某些任意条件增强文档的函数,则它可能会无意中降低精确匹配的相关性,特别是当该函数将增强应用于不匹配的文档或以某种方式干扰精确匹配的评分时。
换句话说,function_score总是会影响query_string的评分,导致评分不正确,进而导致错误匹配。您可以通过设置权重并替换分数来操纵此结果,类似于以下内容:
{
"query": {
"function_score": {
"query": {
"bool": {
"must": [
{
"query_string": {
"analyzer": "cg_analyzer_naziv",
"fields": ["content"],
"query": "\"savo pejovic\"",
"boost": 3
}
}
]
}
},
"boost_mode": "replace",
"functions": [
{
"filter": {
"match_all": {}
},
"weight": 1
}
]
}
}
}
通过将 boost_mode 设置为 "replace",function_score 不会干扰 query_string 查询的评分行为。它将简单地应用定义的评分函数,独立于 query_string 查询生成的分数。这样,query_string 查询就可以按预期运行,而不会受到 function_score 查询的影响。
但我真的不推荐这种方式,我更喜欢使用不同的匹配方法,例如match_phrase,它不会受到function_score的影响。