我在项目中使用基于罗盘的索引。我对字段'name'的基于注释的配置是:
@SearchableProperty(name="name")
@SearchableMetaData(name="ordering_name", index=Index.NOT_ANALYZED)
private String name;
现在,以下值存储为“name”字段:
1. Temp 0 New n/a
2. e/f search
3. c/d search
现在,差异情景的搜索结果如下:
1. 'c/d' -> +(+alias:TempClass +(c/d*)) +(alias:TempClass) -> 1 record found
2. 'n/a' -> +(+alias:TempClass +(n/a*)) +(alias:TempClass) -> 0 record found
3. 'search' -> +(+alias:TempClass +(search*)) +(alias:TempClass) -> 2 records found
因此,当我尝试搜索'n / a'时,它应搜索第一条记录,其值为'Temp 0 New n / a'。
任何帮助都将受到高度赞赏!!!
答案 0 :(得分:1)
在某些时候,您的查询分析与您的文档分析不匹配。
很可能你在内部使用Lucene的StandardAnalyzer进行查询解析,但不是在索引时使用,引爆时为:
@SearchableMetaData(name="ordering_name", index=Index.NOT_ANALYZED))
此分析器中使用的StandardTokenizer将字符/
视为字边界(例如空格),生成标记n
和a
。稍后,StopFilter删除了令牌a
。
以下代码是此解释的示例(输入为"c/d e/f n/a"
):
Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_36);
TokenStream tokenStream = analyzer.tokenStream("CONTENT", new StringReader("c/d e/f n/a"));
CharTermAttribute term = tokenStream.getAttribute(CharTermAttribute.class);
PositionIncrementAttribute position = tokenStream.getAttribute(PositionIncrementAttribute.class);
int pos = 0;
while (tokenStream.incrementToken()) {
String termStr = term.toString();
int incr = position.getPositionIncrement();
if (incr == 0 ) {
System.out.print(" [" + termStr + "]");
} else {
pos += incr;
System.out.println(" " + pos + ": [" + termStr +"]");
}
}
您将看到以下提取的令牌:
1: [c]
2: [d]
3: [e]
4: [f]
5: [n]
请注意,缺少令牌a
的预期位置6:如您所见,Lucene的QueryParser也执行此标记化:
QueryParser parser = new QueryParser(Version.LUCENE_36, "content", new StandardAnalyzer(Version.LUCENE_36));
System.out.println(parser.parse("+n/a*"));
输出结果为:
+content:n
编辑:解决方案是使用WhitespaceAnalyzer,并将字段设置为ANALYZED。以下代码是Lucene下的概念证明:
IndexWriter writer = new IndexWriter(new RAMDirectory(), new IndexWriterConfig(Version.LUCENE_36, new WhitespaceAnalyzer(Version.LUCENE_36)));
Document doc = new Document();
doc.add(new Field("content","Temp 0 New n/a", Store.YES, Index.ANALYZED));
writer.addDocument(doc);
writer.commit();
IndexReader reader = IndexReader.open(writer, true);
IndexSearcher searcher = new IndexSearcher(reader);
BooleanQuery query = new BooleanQuery();
QueryParser parser = new QueryParser(Version.LUCENE_36, "content", new WhitespaceAnalyzer(Version.LUCENE_36));
TopDocs docs = searcher.search(parser.parse("+n/a"), 10);
System.out.println(docs.totalHits);
writer.close();
输出为:1
。