Lucene在QueryParser中忽略/覆盖模糊编辑距离



给定以下QueryParser,查询字符串中有一个FuzzySearch术语:

fun fuzzyquery() {
val query = QueryParser("term", GermanAnalyzer()).parse("field:search~4")
println(query)
}

生成的查询实际上将具有以下表示形式:

field:search~2

因此,~4被重写为~2。我将代码追溯到以下实现:

QueryParserBase

protected Query newFuzzyQuery(Term term, float minimumSimilarity, int prefixLength) {
String text = term.text();
int numEdits = FuzzyQuery.floatToEdits(minimumSimilarity, text.codePointCount(0, text.length()));
return new FuzzyQuery(term, numEdits, prefixLength);
}

模糊查询

public static int floatToEdits(float minimumSimilarity, int termLen) {
if (minimumSimilarity >= 1.0F) {
return (int)Math.min(minimumSimilarity, 2.0F);
} else {
return minimumSimilarity == 0.0F ? 0 : Math.min((int)((1.0D - (double)minimumSimilarity) * (double)termLen), 2);
}
}

如图所示,任何高于2的值都将重置为2。为什么会出现这种情况,以及如何将我想要的模糊编辑距离正确地输入查询解析器?

这可能会越过边界进入"不是一个答案"-但对于一条评论(或几条评论(来说太长了:

为什么会这样

这似乎是一个设计决定。这里的文档中提到了它。

"该值在0和2〃之间

这里有一篇旧文章给出了解释:

"较大的差异要高效计算要昂贵得多,而且Lucene不会处理这些差异">

我不知道这有多正式。

更正式地说,在FuzzyQuery类的JavaDoc中,它声明:

"此查询最多可匹配2个编辑项。更高的距离(尤其是启用了换位(通常是无用的,并且会与术语词典的大量内容相匹配">

如何将我想要的模糊编辑距离正确地输入查询解析器

除非您自定义源代码,否则您不能。

我认为,最好(最不坏?(的替代方案可能是上述FuzzyQueryJavadoc:中提到的方案

"如果你真的想要这样,可以考虑使用n-gram索引技术(例如建议模块中的SpellChecker(">

在这种情况下,要支付的一个价格可能会是一个更大的指数,即使这样,n-gram也不等于编辑距离。我不知道这是否能满足你的需要。

最新更新