模糊检索

模糊检索(Fuzzy 检索)

如果想要搜索与检索词不完全一致的单词,可以使用模糊检索(Fuzzy 检索)。模糊检索是指,当检索词与索引中登记的单词之间的差异(编辑距离)在一定范围内时,将该单词视为匹配进行检索的方法。编辑距离是指将某个单词转换为另一个单词所需的字符插入、删除、替换等操作的最小次数。Fess 默认在这些操作的基础上,还会将相邻 2 个字符的互换也计为 1 次差异,采用达梅劳-莱文斯坦距离(最优字符串对齐)。

使用方法

在希望应用模糊检索的检索词后面添加”~”。

例如,如果想对”fess”这个单词进行模糊检索,可以按如下方式在搜索表单中输入,从而搜索包含与”fess”相近的词(如”fes”等)的文档。

fess~

在”~”后面加上数字,可以指定允许的编辑距离(即允许相差多少个字符)。可指定的值为 0、1、2 中的整数。

fess~1

上述示例将搜索与”fess”编辑距离在 1 以内的单词。

如果省略数字,仅指定”~”,则按编辑距离 2 处理。编辑距离的最大值为 2,即使指定 3 以上的值,也会按 2 处理。

也可以指定字段进行模糊检索。下面的示例将在 title 字段中搜索包含与”fess”相近的词的文档。

title:fess~

如果不指定字段,将以 title 和 content 字段为对象进行模糊检索。

使用条件

使用模糊检索时,请注意以下几点。

  • 模糊检索以单词为单位应用,无法应用于用引号括起来的短语。此外,短语后面添加的数字(例如 "Fess Search"~2)不是模糊检索,而是表示单词间距离的邻近检索。

  • 模糊检索针对索引中已登记的单词进行,检索词不会被重新解析。因此,对于通过 bi-gram 或形态素解析进行分词的日语等文本,可能无法按预期工作。模糊检索主要对英数字单词有效。

  • 模糊检索的检索词会连同大小写在内,原样计算编辑距离。登记到索引中的英文单词通常已转换为小写,因此检索词请使用小写。例如 Fess~1 仅开头的大写 F 就用掉了编辑距离 1,所以结果与 fess~1 不同。另外,Fess~0 由于索引中没有与大写单词 Fess 匹配的词,因此什么都匹配不到(小写的 fess~0 是完全匹配)。

  • 对 1~2 个字符等非常短的单词添加”~”(编辑距离 2)时,替换字符数接近单词长度的词也会匹配。例如 ab~ 除了 ab 和 ac 之外,还会匹配两个字符都不同的 xy。这会增加意料之外的结果,因此对于短单词,请像 ab~1 这样指定较小的编辑距离。

Note

模糊检索的行为可以通过 fess_config.properties 进行调整。

  • query.fuzzy.prefix_length(默认值:0):从开头起完全匹配的字符数。该值越大,允许出现差异的范围就越窄。

  • query.fuzzy.expansions(默认值:50):作为匹配候选展开的单词的最大数量。

  • query.fuzzy.transpositions(默认值:true):指定是否将相邻 2 个字符的互换计为 1 次编辑。当为 true 时采用达梅劳-莱文斯坦距离,当为 false 时采用经典莱文斯坦距离。

Note

即使是不添加”~”的普通检索,Fess 也会针对长度达到一定长度以上(默认为 4 个字符以上)的检索词,出于提高相关度的目的,自动附加轻微加权的模糊匹配作为辅助(query.boost.fuzzy.*)。这主要是用于调整检索结果排序的功能,与通过”~”进行的模糊检索是不同的机制。不过,这种辅助性的匹配也会包含在检索结果中,因此可能会有不包含检索词本身、只包含相差 1 个字符的单词的文档加入结果(包含检索词本身的文档会排在更靠前的位置)。如果想停止这一行为,请将 query.boost.fuzzy.min.length 设置为负值(例如 -1)。

相关主题