当使用“ - ”或通配符时,Lucene.Net不返回预期的搜索结果

时间:2014-11-12 19:45:26

标签: lucene.net

我正在使用Lucene.net 2.9,并试图理解为什么我的查询没有返回预期的结果。

我使用以下函数将字段添加到索引文档。

//add fields to the document
public void AddFacet(Lucene.Net.Documents.Document doc, String facetName, String facetValue)
{
    doc.Add(new Lucene.Net.Documents.Field(facetName, facetValue, Lucene.Net.Documents.Field.Store.YES, Lucene.Net.Documents.Field.Index.NOT_ANALYZED));
}

//snippet of analyzer being used
Lucene.Net.Analysis.Analyzer analyzer = new Lucene.Net.Analysis.Standard.StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29);

//snippet of a simple demo
Lucene.Net.Documents.Document doc = new Lucene.Net.Documents.Document();
AddFacet(doc, "FACET", "INDEX-VALUE-TEST");

据我所知,由于我在向文档添加字段时使用Lucene.Net.Documents.Field.Index.NOT_ANALYZED,因此facetValue不会被标记为术语。

我认为这意味着原始facetValue存储为" INDEX-VALUE-TEST"。如果它被标记化,它将被存储多个条款" INDEX"," VALUE"和" TEST",因为分析器将-解释为停用词。

如果我搜索" INDEX",我的查询将看起来像+(xml:index),它会返回包含" INDEX"的所有文件。用他们的任何条款。这是预期的。

我不了解以下情况:

  1. 如果我搜索" INDEX-VAL",我的查询将会像 +(xml:index-val),不返回任何结果。我可以看到为什么这没有返回任何结果,因为没有通配符。

  2. 如果我搜索" INDE *",我的查询将如下所示     +(xml:inde*),再次没有返回任何结果。我不确定为什么这不会返回任何文件。我希望能够收回包含" INDE"的所有文件。在他们的任何领域。

  3. 如果我搜索" INDEX-VALUE-TEST",我的查询将会像     +(xml:index-value-test)。再一次,没有结果。我希望能找到1份文件。

  4. 如果我将该术语存储为" INDEX-VALUE-TEST",那么为什么#2和#3不会返回结果?我可以看到为什么#1不会,因为它可能需要一个通配符来匹配其余的术语。如果是这样的话,我为什么要搜索" INDEX"没有通配符并获取所有文件?

    我一直在使用this source to understand the indexing files.

    我一直在使用this source to understand the fields I'm adding to the document.

    如果有人能帮助我理解我所缺失的内容,我们将不胜感激。

3 个答案:

答案 0 :(得分:2)

我认为,正确解决这个问题的方法是编写我们自己的解析器/分析器,以便我们可以更好地控制正在发生的事情。目前的努力程度是不合理的(可能直到出现其他问题)。

我的工作是在搜索时用空格替换所有-。它使搜索结果更符合我的预期。这应该没问题,因为分析器通常会以一致的方式为非通配符查询对此字符进行标记。

答案 1 :(得分:0)

根据我的理解,如果使用Lucene.Net.Documents.Field.Index.NOT_ANALYZED索引字段,则搜索将区分大小写。如果您将搜索字符串更改为大写,则可能会收到针对案例#2和#3的结果。如果您在搜索时使用的分析器将所有内容转换为小写,那么您可能需要将该字段索引为小写字符串。

对于案例#3,您可能还需要转义搜索查询中的' - '短划线字符,因此搜索变为+(xml:INDEX \ -VALUE \ -TEST)。因为使用' - '字符进行搜索可以解释为布尔运算符。

答案 2 :(得分:0)

您写道:

  

分析器解释 - 作为停用词。

StandardAnalyzer使用StandardTokenizer对文本进行标记,该标识将连字符( - )解释为punctuation,而不是stop word。实际上,结果是相同的:它会删除连字符。

StandardTokenizer将标记化查询表达式" INDEX-VALUE-TEST"进入三个标记:

( INDEX, VALUE, TEST )

在索引中的单个标记上无法匹配:

( INDEX-VALUE-TEST )

当Lucene在UAX 29中应用Unicode分段规则时,这种对连字符的处理有望在未来发生变化。但这里的问题不是标点符号,因为连字符在" INDEX-VALUE-TEST"不是标点符号。

无论如何,它看起来像你正在搜索字段" xml"而不是" FACET",因为查询解析器产生了这个查询:

  

+(XML:指标值检验)

我说" xml"是索引的默认搜索字段。

您可以使用WhitespaceAnalyzer获得所需的行为,但我建议使用KeywordAnalyzer,这似乎更接近您的意图(将整个字段视为单个标记)。

请注意,您必须使用相同的分析器进行索引和搜索。使用查询解析器时,请指定相关字段:

FACET:INDEX-VALUE-TEST

除了KeywordAnalyzer for FACET之外,如果您需要StandardAnalyzer用于其他字段,您可以使用PerFieldAnalyzerWrapper