如何在Lucene.Net中检索大型索引的所有索引(但未存储)条款?
我这样做的原因是因为我正在从Lucene.Net迁移到最新的Apache Lucene版本,并且索引格式在版本上发生了多次变化。我通过阅读术语来迁移数据,然后再将它们索引到新格式。我知道Lucene编解码器包,但是它不能为Lucene.Net使用的格式提供足够的向后兼容性。
有类似的问题,例如Find list of terms indexed by Lucene
但是,上述方法的问题是IndexReader.Terms
从索引中读取每个单词,这会导致大型索引上的OutOfMemoryException
。
如何以合理的方式从大型索引中获取所有条款,而不会有内存不足的风险?
示例代码(在调用OutOfMemoryException
时抛出reader.Terms(orderBy)
):
var results = new List<string>();
var orderBy = new Term("MyField", string.Empty);
using (var reader = IndexReader.Open(FSDirectory.Open(_indexPath), true))
using (var termEnum = reader.Terms(orderBy))
{
for (var term = termEnum.Term; term != null; termEnum.Next(), term = termEnum.Term)
{
if (term.Field != "MyField")
{
break;
}
results.Add(term.Text);
}
}
答案 0 :(得分:2)
查看代码,在这种情况下,您似乎可能会耗尽内存的唯一原因是因为您正在将所有术语写入List<string>
。为避免内存不足,您应该将字符串保存到磁盘。
var orderBy = new Term("MyField", string.Empty);
using (var reader = IndexReader.Open(FSDirectory.Open(_indexPath), true))
using (var termEnum = reader.Terms(orderBy))
using (var stream = new FileStream("TheFile.txt", FileMode.Create, FileAccess.Write))
using (var writer = new StreamWriter(stream))
{
for (var term = termEnum.Term; term != null; termEnum.Next(), term = termEnum.Term)
{
if (term.Field != "MyField")
{
break;
}
writer.WriteLine(term.Text);
}
}
虽然这可能会回答你的问题,但是你试图从索引中提取更多的术语而不是你的记忆,这表明你提出错误的问题。我建议你提出另一个问题来说明你正在尝试的实际任务 - 最有可能的方法是从索引中读取所有这些原始数据(或更高效)。