嗨, 我的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已未过时。)的标准调用IndexReader.Open一个FSDirectory会用读者的一个游泳池,一个为每个段。
IndexReader.GetCacheKey
IndexReader.Open
FSDirectory
您应该始终将最里面的读取器传递给FieldCache。签出ReaderUtil一些帮助者的资料,以检索其中包含文档的个人阅读器。文档ID不会在段中更改,将其描述为不可预测/易变的含义是在两次索引提交之间更改。可以对删除的文档进行验证,对段进行合并以及执行此类操作。
ReaderUtil
提交需要从磁盘中删除该段(合并/优化),这意味着新的读取器将没有池化段读取器,并且在关闭所有较旧的读取器后,垃圾回收会将其删除。
永远不要打电话FieldCache.PurgeAllCaches()。它仅用于测试,而不是用于生产。
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];