正确存储/检索termVector

时间:2019-05-29 19:15:51

标签: indexing lucene lucene.net

我正在使用Lucene.NET 4.8-beta00005。

我在文档中有一个“名称”字段,定义如下:

doc.Add(CreateField(NameField, entry.Name.ToLower()));
writer.AddDocument(doc);

CreateField的实现方式如下

private static Field CreateField(string fieldName, string fieldValue)
{
    return new Field(fieldName, fieldValue, new FieldType() {IsIndexed = true, IsStored = true, IsTokenized = true, StoreTermVectors = true, StoreTermVectorPositions = true, StoreTermVectorOffsets = true, StoreTermVectorPayloads = true});
}

为“名称”字段分配了StandardAnalyzer

然后在我的CustomScoreProvider中,从术语向量中检索这些术语,如下所示:

private List<string> GetDocumentTerms(int doc, string fieldName)
{
    var indexReader = m_context.Reader;
    var termVector = indexReader.GetTermVector(doc, fieldName);
    var termsEnum = termVector.GetIterator(null);

    BytesRef termBytesRef;
    termBytesRef = termsEnum.Next();

    var documentTerms = new List<string>();

    while (termBytesRef != null)
    {
        //removing trailing \0 (padded to 16 bytes)
        var termText = Encoding.Default.GetString(termBytesRef.Bytes).Replace("\0", "");
        documentTerms.Add(termText);
        termBytesRef = termsEnum.Next();
    }

    return documentTerms;
}

现在我有一个文档,其中“名称”字段的值是“ dan gertler diamonds ltd。”。

所以我期望的术语向量是:

  

丹·格特勒钻石有限公司

但是我的GetDocumentTerms给我以下术语:

  

dan diamonds gertlers ltdtlers

我在该字段中用作StandardAnalyzer,所以我不希望它对字段中的原始单词进行太多转换(并且我确实使用此特定名称和StandardAnalyzer进行了检查)。

我在这里做错什么以及如何解决?

编辑:我正在用每个字段的分析器手动扩展这些术语,并将它们作为单独的字符串存储在单独的String字段中。

1 个答案:

答案 0 :(得分:1)

如果要以正确的顺序获取条款,则还必须使用位置信息。测试此代码:

Terms terms = indexReader.GetTermVector(doc, fieldName);
if (terms != null)
{
    var termIterator = terms.GetIterator(null);
    BytesRef bytestring;
    var documentTerms = new List<Tuple<int, string>>();
    while ((bytestring = termIterator.Next()) != null)
    {
        var docsAndPositions = termIterator.DocsAndPositions(null, null, DocsAndPositionsFlags.OFFSETS);
        docsAndPositions.NextDoc();
        int position;
        for(int left = docsAndPositions.Freq; left > 0; left--)
        {
            position = docsAndPositions.NextPosition();
            documentTerms.Add(new Tuple<int, string>(position, bytestring.Utf8ToString()));
        }
    }
    documentTerms.Sort((word1, word2) => word1.Item1.CompareTo(word2.Item1));
    foreach (var word in documentTerms)
    {
        Console.WriteLine("{0} {1} {2}", fieldName, word.Item1, word.Item2);
    }
}

此代码还可以处理在多个地方使用相同术语(单词)的情况。

相关问题