经常更新索引的FieldCache

你好
我的Lucene索引经常用新记录更新,索引中有5,000,000条记录,并且正在使用FieldCache缓存我的一个数字字段.但是在更新索引之后,需要花费一些时间来重新加载FieldCache(即重新加载缓存,导致文档说DocID不可靠),所以我如何通过仅将新添加的DocID添加到FieldCache来最小化此开销,导致此功能成为我的瓶颈应用.


IndexReader reader = IndexReader.Open(diskDir);
int[] dateArr = FieldCache_Fields.DEFAULT.GetInts(reader, "newsdate"); // This line takes 4 seconds to load the array
dateArr = FieldCache_Fields.DEFAULT.GetInts(reader, "newsdate"); // this line takes 0 second as we expected
// HERE we add some document to index and we need to reload the index to reflect changes

reader = reader.Reopen();
dateArr = FieldCache_Fields.DEFAULT.GetInts(reader, "newsdate"); // This takes 4 second again to load the array

我想要一种通过仅将新添加的文档添加到数组中的索引中来最大程度地减少这种时间的机制,有一种类似于http://invertedindex.blogspot.com/2009/04/lucene-dociduid-mapping-and-payload.html的技术
来提高性能,但是它仍然加载我们已经拥有的所有文档,并且我认为如果我们找到一种仅将新添加的文档添加到数组中的方法,则无需重新加载所有文档

解决方法:

FieldCache使用弱引用来将索引读取器用作其缓存的键. (通过调用已经过时的IndexReader.GetCacheKey.)使用FSDirectory对IndexReader.Open的标准调用将使用一组读者,每个段一个.

您应该始终将最里面的读取器传递给FieldCache.查看ReaderUtil中的一些帮助者资料,以检索文档中包含的单个阅读器.文档ID不会在段中更改,将其描述为不可预测/易变的含义是在两次索引提交之间更改.可以对删除的文档进行验证,对段进行合并以及执行此类操作.

提交需要从磁盘中删除该段(合并/优化),这意味着新的读取器将不会具有池化段读取器,并且垃圾收集将在所有较旧的读取器关闭后立即将其删除.

永远不要调用FieldCache.PurgeAllCaches().它仅用于测试,而不是用于生产.

新增2011-04-03;使用子阅读器的示例代码.

var directory = FSDirectory.Open(new DirectoryInfo("index"));
var reader = IndexReader.Open(directory, readOnly: true);
var documentId = 1337;

// Grab all subreaders.
var subReaders = new List<IndexReader>();
ReaderUtil.GatherSubReaders(subReaders, reader);

// Loop through all subreaders. While subReaderId is higher than the
// maximum document id in the subreader, go to next.
var subReaderId = documentId;
var subReader = subReaders.First(sub => {
    if (sub.MaxDoc() < subReaderId) {
        subReaderId -= sub.MaxDoc();
        return false;
    }

    return true;
});

var values = FieldCache_Fields.DEFAULT.GetInts(subReader, "newsdate");
var value = values[subReaderId];
上一篇:java – Lucene按URL搜索


下一篇:c-使用整数列表文档进行全文搜索的最佳方法