0

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

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

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

第一个例子:

我们有 5 个文件:

文件 1:字段A:1;字段B:你好世界

文件 2:字段 A:2;FieldB:世界你好!

文件 3:字段 A:3;字段B:你好世界

文件 4:字段 A:4;字段B:任何东西

文件 5:字段 A:5;字段B:你好世界

当我进行像“B:hello world”这样的搜索时,它应该返回文档 1、3 和 5,但它只返回 1 和 3。

当我进行像“A:5”这样的搜索时,它会返回文档 5,字段 B 的值是“hello world”。

第二个例子:(一个令牌)

文件 6:字段 A:6;字段B:令牌

文件 7:字段A:7;字段B:令牌

文件 8:字段 A:8;字段B:TOKEN

Doc 9: FieldA:9 FieldB: token

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

我正在使用 WhitespaceAnalyzer 并且两个字段都不是 NOT_ANALYZED。

索引生成器主

...

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 的行为方式与应用程序相同,那么我做错了什么?

提前致谢!

4

2 回答 2

1

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

如果您正在索引值“hello there”,则使用TermQuery“hello”搜索将找不到任何内容。如果您索引了“Hello”、“hello!”甚至“hello”,它也不会找到任何东西。它将区分大小写、标点符号、空格等,并且需要对整个输入进行匹配。所以我怀疑,您未找到的文件在这些方面存在问题。

于 2013-11-15T00:11:16.600 回答
1

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

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

通过使用短语表达式,您可能会得到您期望的结果:B:"hello world"。但你可能不会;当它构建一个对象WhitespaceAnalyzer时,会将这个短语分成两个标记。Query

KeywordAnalyzer如我对另一个问题的回答中所述,您可以通过使用字段 B 来解决该问题。

于 2013-11-15T09:35:05.850 回答