java Lucene:前缀令牌匹配或精确匹配的前缀
我有几千根这样的线
- 福吧赫普
- 福巴德普酒店
- 巴兹:还有别的吗
我想提供一个有效的搜索,以便
- “foo bar”(标记化前缀)
- “foo herp”(跳过标记)
- “foo bar-”(精确前缀)
- “Bar Herp”(中间的精确字符串)
- “foo-ba”(一个完整的标记和另一个标记的前缀)
等等。 全部返回第一个字符串(可能还有其他字符串),但是
- “herp foo”(顺序错误,不重要)
- “foo blerp”(并非所有代币)
- “murp herp”(并非所有代币)
不要
也就是说,精确的前缀匹配和正确顺序的标记(可能是前缀)匹配都应该匹配,与大小写无关,但查询中的所有标记都必须在文档中
我已经使用一个StandardAnalyzer和一个带有前缀查询的公共QueryParser设置了典型的Lucene示例
我想我可能需要一个BinaryQuery来声明我需要查询中的所有标记都出现在文档中,但我不能完全弄清楚如何获取标记来构建它(查询由用户提供)。我还意识到,使用StringField而不是TextField可以提供与令牌匹配相反的精确字符串匹配,但我不确定这是否是我可以与上述内容结合使用的内容
我该怎么做?我甚至不需要用Lucene来做这件事,但它看起来很合适
# 1 楼答案
第一个(非关键)有点棘手,但要确保在所有结果中找到查询中的所有术语,只需将所有查询术语设置为必需。您可以使用添加的plus运算符来执行此操作:
+foo +bar
+foo +ba*
(如果你想处理前缀,你需要添加通配符来指定它,或者可能使用ngram标记器,或者类似的东西)或者,您可以使用^{} 将默认运算符设置为
AND
在
herp foo
和foo herp
的情况下,我认为短语slop可能会让你达到你需要的地方。交换术语顺序会增加两个距离,因此:"foo herp"~2
:匹配“Foo-Bar-Herp”"herp foo"~2
:没有但是短语查询不支持通配符,所以如果需要将通配符与前缀词结合使用,就会遇到问题
如果您想在不改变顺序的情况下允许更多的slop,那么我相信您已经超出了
QueryParser
表达查询的能力,需要转到SpanQuery
API来手动构造查询手动构造查询,可以执行以下操作:
按顺序查找第一个术语(精确匹配)和第二个术语的前缀,它们之间的术语不超过五个