我正在尝试构建一个通过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的行为方式与应用程序相同,我做错了什么?
提前致谢!
答案 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中所述。