Lucene搜索会跳过一些结果

时间:2013-11-14 19:37:27

标签: lucene luke

我正在尝试构建一个通过Lucene索引实现搜索系统的应用程序。现在索引是构建的,我可以搜索索引上的文档,一切似乎都运行正常但是,当我使用许多文档中使用的字段进行搜索时,分析器只返回一些文档。我试图使用Luke进行相同的搜索并且行为方式相同。

即:我的索引有2个字段:

字段A:唯一的标识符。 字段B:字符串。

第一个例子:

我们有5个文件:

Doc 1:FieldA:1; FieldB: hello world

Doc 2:FieldA:2; FieldB:你好世界!

Doc 3:FieldA:3; FieldB: hello world

Doc 4:FieldA:4; FieldB:任何

Doc 5:FieldA:5; FieldB: hello world

当我进行“B:hello world”之类的搜索时,它应返回文档1,3和5,但它只返回1和3.

当我搜索“A:5”时,它返回文档5,字段B值为“hello world”。

第二个例子:(一个标记)

Doc 6:FieldA:6; FieldB:的令牌

Doc 7:FieldA:7; FieldB:的令牌

Doc 8:FieldA:8; FieldB:的 TOKEN

Doc 9:FieldA:9 FieldB:令牌

当我搜索FieldB:“令牌”时,它只返回Doc 6和Doc 9.我能找到Doc 7的唯一方法是通过FieldA进行搜索。

我使用的是WhitespaceAnalyzer,并且两个字段都没有被分析。

IndexGenerator Main

...

IndexWriter writer = new IndexWriter(directory, new WhitespaceAnalyzer(), true, IndexWriter.MaxFieldLength.UNLIMITED);;
writer.setRAMBufferSizeMB(200);

List<Work> works = getWorks(); //Retrieves the information from the DB

for (Work work: works) {

   Document luceneDocument = createLuceneDocument(work);
   writer.addDocument(luceneDocument);

}
writer.commit();

...

CreateLuceneDocument方法:

private static Document createLuceneDocument(Work work) {

 try {
   Document luceneDoc = new Document();

   ...

   Field id = new Field("ID", work.getId(),Field.Store.YES,Field.Index.NOT_ANALYZED);
   luceneDoc.add(id);

   Field name = new Field("NAME", work.getName(),Field.Store.YES,Field.Index.NOT_ANALYZED);
   luceneDoc.add(name);

   ...

   return document;

   }
   catch (LuceneException e) {
       ...
   }
}

我注意到未返回的文档的分数值较低。假设创建索引时出现问题是因为Luke的行为方式与应用程序相同,我做错了什么?

提前致谢!

2 个答案:

答案 0 :(得分:1)

我想,我会在这里把你的怀疑告诉你。您说您使用的是WhitespaceAnalyzer,但由于您的字段为NOT_ANALYZED,因此该分析器对索引内容没有任何作用。它们被精确地索引,作为单个标记。

如果要将值“hello there”编入索引,则在“hello”上使用TermQuery进行搜索将找不到任何内容。如果您索引“Hello”,“hello!”,甚至“hello”,它也不会发现任何内容。它将是case,punctuation,whitespace等敏感,并且需要匹配整个输入。所以我怀疑,你的未找到的文件在这些方面存在问题。

答案 1 :(得分:1)

Lucene会将搜索表达式B:hello world解析为B:hello D:world,这是两个术语的表达。这里D是默认搜索字段,可能是您对@ femtoRgon答案的评论中提到的“另一个Field”。

我猜测结果包括文档1和3,因为它们匹配字段D中的标记“world”,但是此标记在文档5字段D中不存在。但只有当默认搜索运算符不是OR时才可能AND,因为B:hello无法匹配这些文档。

您可以使用词组表达式获得您期望的结果:B:"hello world"。但你可能不会; WhitespaceAnalyzer在构建Query对象时会将此短语分为两个标记。

您可以使用KeywordAnalyzer对字段B解决问题,如answer to another question中所述。