[英]Scrub Lucene search terms with the Standard Analyzer
我们正在根据搜索字词字符串构建布尔查询,以搜索我们的Lucene索引。 我希望使用标准分析器(我们用于索引的分析器)分析这些字符串。 例如, foo-bar 1-2-3
应该被分解为foo
, bar
, 1-2-3
因为Lucene文档指出连字符导致数字保持在一起但单词被标记化。 做这个的最好方式是什么?
目前,我正在通过QueryParser运行搜索词字符串。
QueryParser parser = new QueryParser("", new StandardAnalyzer());
Query query = parser.parse(aSearchTermString);
问题是插入了引号。 例如, foo-bar 1-2-3
变为"foo bar"
( 1-2-3
,它不会返回任何内容,因为Lucene会将foo-bar
标记为foo
和bar
。
我绝对不希望通过用replace
删除引号来解决这种情况,因为我觉得我可能丢失了一些东西或做错了什么。
实际上,对于StandardAnalyzer
我得到了不同的结果。 考虑以下代码(使用Lucene v4):
public class Tokens {
private static void printTokens(String string, Analyzer analyzer) throws IOException {
System.out.println("Using " + analyzer.getClass().getName());
TokenStream ts = analyzer.tokenStream("default", new StringReader(string));
OffsetAttribute offsetAttribute = ts.addAttribute(OffsetAttribute.class);
CharTermAttribute charTermAttribute = ts.addAttribute(CharTermAttribute.class);
while(ts.incrementToken()) {
int startOffset = offsetAttribute.startOffset();
int endOffset = offsetAttribute.endOffset();
String term = charTermAttribute.toString();
System.out.println(term + " (" + startOffset + " " + endOffset + ")");
}
System.out.println();
}
public static void main(String[] args) throws IOException {
printTokens("foo-bar 1-2-3", new StandardAnalyzer(Version.LUCENE_40));
printTokens("foo-bar 1-2-3", new ClassicAnalyzer(Version.LUCENE_40));
QueryParser standardQP = new QueryParser(Version.LUCENE_40, "", new StandardAnalyzer(Version.LUCENE_40));
BooleanQuery q1 = (BooleanQuery) standardQP.parse("someField:(foo\\-bar\\ 1\\-2\\-3)");
System.out.println(q1.toString() + " # of clauses:" + q1.getClauses().length);
}
}
以上印刷品:
Using org.apache.lucene.analysis.standard.StandardAnalyzer
foo (0 3)
bar (4 7)
1 (8 9)
2 (10 11)
3 (12 13)
Using org.apache.lucene.analysis.standard.ClassicAnalyzer
foo (0 3)
bar (4 7)
1-2-3 (8 13)
someField:foo someField:bar someField:1 someField:2 someField:3 # of clauses:5
因此,以上代码证明StandardAnalyzer
(与ClassicAnalyzer
不同)应该将1-2-3
拆分为不同的令牌-完全按照您的意愿。 对于查询,您需要转义每个关键字,包括空格,否则QP认为这具有不同的含义。
如果您不想转义查询字符串,则始终可以手动将其标记化(如上述printTokens
方法中的标记),然后用TermQuery
包装每个标记并将所有TermQueries堆叠到BooleanQuery
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.