首页 > 解决方案 > 正确存储/检索 termVector

问题描述

我正在使用 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给了我以下条款:

丹·戴蒙德·格特勒斯有限公司

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

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

编辑:我正在使用每个字段的分析器手动提取这些术语,并将它们放在一个单独的字符串字段中作为暂时的解决方法。

标签: indexinglucenelucene.net

解决方案


如果您想以正确的顺序获取术语,还必须使用位置信息。测试这段代码:

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

此代码还处理您在多个地方具有相同术语(单词)的情况。


推荐阅读