Lucene搜索跳过一些结果

Lucene搜索跳过一些结果,lucene,luke,Lucene,Luke,我正在尝试构建一个应用程序,在Lucene索引上实现一个搜索系统。现在索引已经建立,我可以在索引上搜索文档,一切似乎都很正常,但是,当我使用许多文档中使用的字段进行搜索时,分析器只返回一些文档。我试着使用Luke进行同样的搜索,并且表现出同样的方式 i、 e:我的索引有两个字段: 字段A:唯一的标识符。 字段B:字符串 第一个示例: 我们有5份文件: 文件1:FieldA:1;FieldB:你好,世界 文件2:FieldA:2;世界你好 文件3:FieldA:3;FieldB:你好,世界 文件4

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

i、 e:我的索引有两个字段:

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

第一个示例:

我们有5份文件:

文件1:FieldA:1;FieldB:你好,世界

文件2:FieldA:2;世界你好

文件3:FieldA:3;FieldB:你好,世界

文件4:FieldA:4;B:有什么事吗

文件5:FieldA:5;FieldB:你好,世界

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

当我进行类似“a:5”的搜索时,它返回文档5,字段B的值是“hello world”

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

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

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

文件8:FieldA:8;字段B:令牌

文件9:FieldA:9 FieldB:token

当我搜索FieldB:“token”时,它只返回文档6和文档9。我能找到7号文件的唯一方法是按字段A搜索

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

索引生成器主

...

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();

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


提前谢谢

我想我会在这里向你表示我的怀疑。您说您正在使用
WhitespaceAnalyzer
,但由于您的字段未经分析
,该分析器对索引内容没有任何作用。它们作为单个标记被精确地索引


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

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

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

您可以通过使用短语表达式获得预期的结果:
B:“hello world”
。但你不可以
WhitespaceAnalyzer
在构建
Query
对象时会将此短语分成两个标记


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

在您的示例中,我没有看到任何会导致此类问题的内容。我也不明白,你怎么能对一个查询中找不到的文档进行评分。也许更多的信息会有用,比如你的搜索代码,以及一些关于这个问题实际发生的数据的进一步信息?谢谢@femtoRgon!这个例子是解释发生了什么的最简单的方法。实际索引有12个字段,比示例复杂得多。正如我在第一篇文章中所说的,即使字段满足了搜索请求,Luke也不会显示文档。因此,问题应该是在索引生成过程中。我将添加有关索引生成的更多信息。您在哪里看到“未返回的文档具有较低的分数值”?我有两个具有相同值的字段,第一个字段未分析,这是我遇到的问题,第二个字段具有标记,并已分析,效果良好。我尝试在第一个字段中搜索“hello world”,得到两个结果,在第二个字段中的相同搜索返回3个字段(如下示例)。当我尝试只使用一个令牌搜索字符串时,也会发生同样的情况,因此问题与令牌无关。当我通过第二个字段搜索时,我得到了第一个字段搜索时没有返回的文档,并且所有文档的分值都很低,即使字段值相同。这是对的@femtoRgon,我希望将这些字段作为单个标记进行索引,因为我正在使用另一个
字段
使用不同的标记对相同的值进行索引。问题是,我正在搜索“hello world”,只找到了3个文档中的2个(为了澄清这一点,我对示例进行了一些更改)。再次感谢+感谢1@femtoRgon帮助我回答了一个不够清晰的问题。我在只有一个令牌的字段中以及在有多个令牌的字段中都遇到了这个问题。我试图使用KeywordAnalyzer搜索Luke,但我得到了相同的结果,可能是因为索引是使用WhitespaceAnalyzer生成的,但它是否影响到1个令牌字段??谢谢你的帮助@groverboy@user2993510取决于“1令牌字段”的含义。需要说明的是,如果字段B的值“hello world”是用
创建的,而不是用
分析的
创建的,那么该字段有1个令牌[hello world]。如果字段C的值“hello world”是通过
分析创建的
,那么该字段有2个标记[hello][world]。@user2993510请给出一个您尝试使用Luke和
关键字分析器
的搜索表达式示例?我在解释中添加了另一个示例
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) {
       ...
   }
}