如果我搜索“bahnhofstrasse”,我希望Lucene找到一个包含术语“bahnhofstr”的文档,即我不仅希望查找包含我的搜索词是前缀的条款的文档,还要查找文档包含本身就是我的搜索词的前缀的术语...
我该怎么做?
答案 0 :(得分:1)
如果我理解正确,并且您的搜索字符串是一个确切的字符串,您可以在Lucene中设置queryParser.setAllowLeadingWildcard(true);
以允许进行通配符搜索(这可能会也可能不会很慢 - 我已经合理地看到了它们快速,但在只有60,000多个Lucene文档的情况下)。
您的示例查询语法可能类似于:
*bahnhofstr bahnhofstr*
或可能(尚未测试过)只是:
*bahnhofstr*
答案 1 :(得分:0)
我认为模糊查询可能对您最有帮助。这将根据您查询中的Levenshtein距离对条款进行评分。如果没有指定最小相似度,它将有效地匹配每个可用术语。这可以使它低于高性能,但确实能达到你想要的效果。
模糊查询由〜字符表示,例如:
firstname:bahnhofstr~
或者具有最小相似度(0到1之间的数字,0是最宽松的,没有最小值)
firstname:bahnhofstr~0.4
或者,如果您要构建自己的查询,请使用FuzzyQuery
这并不完全符合您的要求,但却是最简单的接近方式。
至于你正在寻找什么,我不知道一个简单的Lucene调用来实现它。我可能只是将该术语拆分为一系列术语查询,您可以在查询字符串中表示如下:
firstname:b
firstname:ba
firstname:bah
firstname:bahn
firstname:bahnh
firstname:bahnho
firstname:bahnhof
firstname:bahnhofs
firstname:bahnhofst
firstname:bahnhofstr*
顺便说一下,我自己实际上不会为它生成一个查询字符串。我自己构建了TermQuery和PrefixQuery对象。
得分会有点扭曲,我可能会更长时间地提高更长的查询以获得更好的排序,但这是我想到的方法,可以很容易地完成你正在寻找的东西。 DisjunctionMaxQuery可以帮助您使用其他术语,并获得更合理的评分。
希望模糊查询适合你。似乎是一个更好的解决方案。
另一种选择,如果你有很多需要这种性质的查询,可能在索引时将字段标记为n-gram(参见NGramTokenizer),这将允许你有效地使用{{ 3}}以达到你想要的结果。