罗盘查询包含/(斜杠)

时间:2012-04-26 10:33:27

标签: java lucene indexing compass-lucene

我在项目中使用基于罗盘的索引。我对字段'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'。

任何帮助都将受到高度赞赏!!!

1 个答案:

答案 0 :(得分:1)

在某些时候,您的查询分析与您的文档分析不匹配。

很可能你在内部使用Lucene的StandardAnalyzer进行查询解析,但不是在索引时使用,引爆时为:

@SearchableMetaData(name="ordering_name", index=Index.NOT_ANALYZED))

此分析器中使用的StandardTokenizer将字符/视为字边界(例如空格),生成标记na。稍后,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