我们使用 elasticsearch 来搜索地址数据,并且为了非精确匹配,我们包含了街道名称的字段变体,它使用 ngram 标记器(具体为三元组)进行分析。我们对该字段的查询使用“3<75%”的最小应该匹配子句,这意味着“如果搜索词中有 3 个或更少的三元组,那么它们都必须匹配。如果超过 3 个,则其中 75% 必须匹配'
通常这可以正常工作,但在某些情况下我们会得到这样的意外结果
我们搜索“Uhland”并找到“Am Maschlandgraben”。据我所知,发生的情况是“Uhland”被拆分为“uhl”、“hla”、“lan”、“and”,这 4 个三元组中的 3 个可以与“Am MascHLANDgraben”的三元组匹配(匹配部分大写)。所以,四分之三是 75% 满足我们的“3<75%”要求,所以它变成了匹配。
所以 75% 的匹配有一个“方向性”(因为没有更好的词)。它只查看/计算搜索词中的词数,并忽略索引文档中有多少三元组不匹配。
有人可能会争辩说,在该示例中不满足 75% 的匹配要求,因为“Am Maschlandgraben”的 13 个三元组中有 10 个与“Uhland”的三元组不匹配。事实上,如果您反转查询并搜索“Am Maschlandgraben”,您将找不到“Uhland”作为匹配项。因为现在“方向性”颠倒了,查询发现13个三元组中只有3个匹配,不符合“3<75%”的要求
我想弄清楚的是如何修改查询,使 75% 的匹配没有“方向性”,并且始终必须在比较的“双方”上匹配。所以继续上面的例子,我既不希望“Uhland”匹配“Am Maschlandgraben”,也不希望“Am Maschlandgraben”匹配“Uhland”
所以我想,用现实生活中的语言来说,而不是“75% 的搜索词三元组需要匹配索引文档”,我希望“75% 的搜索词和索引文档三元组需要匹配”
我希望我能很好地传达我的意图(英语不是我的母语)
这是我们的查询现在看起来如何的示例_
{
"query": {
"bool": {
"should": [
{
"match": {
"address.street.trigram": {
"query": "Uhland",
"minimum_should_match": "3<75%"
}
}
}
]
}
}
}