Fuzzy Query
模糊查询基于”Levenshtein distance“ 编辑距离进行文档匹配相似度
“Levenshtein distance” 下方有解释
模糊(fuzzy)查询生成的匹配词最大的编辑距离在fuzziness属性中指定,然后检查分词字典,以确定这些生成的分词在哪些索引中实际存在。最后查询使用了max_expansions 来匹配单词。
如下是一个简单的案例:
GET /_search
{
"query": {
"fuzzy" : { "user" : "ki" }
}
}
使用更多的设置:
GET /_search
{
"query": {
"fuzzy" : {
"user" : {
"value": "ki",
"boost": 1.0,
"fuzziness": 2,
"prefix_length": 0,
"max_expansions": 100
}
}
}
}
参数说明
fuzziness:最大的编辑距离,默认AUTO(详情见下方)
prefix_length:不能被 “模糊化” 的初始字符数。 大部分的拼写错误发生在词的结尾,而不是词的开始。 例如通过将 prefix_length 设置为 3 ,你可能够显著降低匹配的词项数量。
boost:设置查询权重
max_expansions:默认长度为50, 如果一个模糊查询扩展了三个或四个模糊选项, 这些新的模糊选项也许是有意义的。如果它产生 1000 个模糊选项,那么就基本没有意义了。设置 max_expansions用来限制将产生的模糊选项的总数量。模糊查询将收集匹配词项直到达到 max_expansions 的限制。
transpositions:是否支持模糊换位(ab→ba)。默认是true。
Fuzziness
模糊匹配 对待 “模糊” 相似的两个词似乎是同一个词。 首先,我们需要对我们所说的 模糊性 进行定义。 在1965年,Vladimir Levenshtein 开发出了 Levenshtein distance, 用来度量从一个单词转换到另一个单词需要多少次单字符编辑。他提出了三种类型的单字符编辑:
一个字符 替换 另一个字符: _f_ox → _b_ox
插入 一个新的字符:sic → sic_k_
删除 一个字符:b_l_ack → back
Frederick Damerau 后来在这些操作基础上做了一个扩展:
相邻两个字符的 换位 : _st_ar → _ts_ar
举个例子,将单词 bieber 转换成 beaver 需要下面几个步骤:
把 b 替换成 v :bie_b_er → bie_v_er
把 i 替换成 a :b_i_ever → b_a_ ever
把 e 和 a 进行换位:b_ae_ver → b_ea_ver
这三个步骤表示 Damerau-Levenshtein edit distance 编辑距离为 3 。
显然,从 beaver 转换成 bieber 是一个很长的过程—他们相距甚远而不能视为一个简单的拼写错误。 Damerau 发现 80% 的拼写错误编辑距离为 1 。换句话说, 80% 的拼写错误可以对原始字符串用 单次编辑 进行修正。
Elasticsearch 指定了 fuzziness 参数支持对最大编辑距离的配置,默认为 2 。
当然,单次编辑对字符串的影响取决于字符串的长度。对单词 hat 两次编辑能够产生 mad , 所以对一个只有 3 个字符长度的字符串允许两次编辑显然太多了。 fuzziness 参数可以被设置为 AUTO ,这将导致以下的最大编辑距离:
字符串只有 1 到 2 个字符时是 0
字符串有 3 、 4 或者 5 个字符时是 1
字符串大于 5 个字符时是 2
当然,你可能会发现编辑距离 2 仍然是太多了,返回的结果似乎并不相关。 把最大 fuzziness 设置为 1 ,你可以得到更好的结果和更好的性能。
This query can be very heavy if prefix_length is set to 0 and if max_expansions is set to a high number. It could result in every term in the index being examined! 如果将prefix_length设置为0,并且将max_expanations设置为高值,则此查询可能非常繁重。它可能导致索引中的每一项都被检查!