给定以下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个编辑项。更高的距离(尤其是启用了换位(通常是无用的,并且会与术语词典的大量内容相匹配">
如何将我想要的模糊编辑距离正确地输入查询解析器
除非您自定义源代码,否则您不能。
我认为,最好(最不坏?(的替代方案可能是上述FuzzyQuery
Javadoc:中提到的方案
"如果你真的想要这样,可以考虑使用n-gram索引技术(例如建议模块中的SpellChecker(">
在这种情况下,要支付的一个价格可能会是一个更大的指数,即使这样,n-gram也不等于编辑距离。我不知道这是否能满足你的需要。