indexing - 正确存储/检索 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)。
我在这里做错了什么以及如何解决?
编辑:我正在使用每个字段的分析器手动提取这些术语,并将它们放在一个单独的字符串字段中作为暂时的解决方法。
解决方案
如果您想以正确的顺序获取术语,还必须使用位置信息。测试这段代码:
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);
}
}
此代码还处理您在多个地方具有相同术语(单词)的情况。
推荐阅读
- apache-kafka - 读取 Kafka 消息并设置该消息由客户端处理
- python - 如何仅合并熊猫数据框中某列的行中没有值的行
- php - 模式上的更新按钮不起作用codeigniter ajax
- r - 函数不处理 R 中的输入参数
- javascript - CSV 到使用 Java/Javascript 的自定义 XML
- android - Android getLastKnownLocation 不更新
- php - PHP preg_split 用于带有大写和自定义字符的新行
- javascript - 在原型之前获取字符串的值
- angularjs - 错误:无法读取 null 的属性“令牌”
- javascript - 从对象数组中选择特定对象jQuery