Java 如何在lucene文档上迭代和更新文档?
我有迭代和更新文档的简单代码。索引太大–数百万文档,10-20gb。 这是一个伪代码:Java 如何在lucene文档上迭代和更新文档?,java,lucene,Java,Lucene,我有迭代和更新文档的简单代码。索引太大–数百万文档,10-20gb。 这是一个伪代码: liveDocs = MultiFields.getLiveDocs(reader); docsEnum = MultiFields.getTermDocsEnum(reader, MultiFields.getLiveDocs(reader), field, bytesRef); while ((doc = docsEnum.nextDoc()) != DocsEnum.NO_MORE_DOCS) {
liveDocs = MultiFields.getLiveDocs(reader);
docsEnum = MultiFields.getTermDocsEnum(reader,
MultiFields.getLiveDocs(reader), field, bytesRef);
while ((doc = docsEnum.nextDoc()) != DocsEnum.NO_MORE_DOCS) {
oldDocument = reader.document(doc);
// some updates
writer.updateDocument(term, newDocument, analyzer);
break;
// simple flush policy
if(doc % 10000 == 0){
writer.commit();
}
}
DocsEnum与它初始化的reader正常工作。但和读卡器相关的索引段(文件)在读卡器打开之前不会被删除,索引大小在每次更新迭代中都会增加一倍。工作一天后,索引大小为TB!
如果关闭所有读写器并重新打开索引,旧的段将被删除。
如何在不泄漏磁盘文件的情况下正确迭代和更新文档
我使用Java1.7和Lucene4.8,这是我找到的最好的解决方案——使用IndexSearcher.search()和&IndexSearcher.searchAfter() 大概是这样的:
// inside iterator
TopDocs docs;
if (lastScore == null) {
docs = searcher.search(query, filter, limit, Sort.INDEXORDER, false, false);
} else {
docs = searcher.searchAfter(lastScore, query, filter, limit, Sort.INDEXORDER, false, false);
}
lastScore = docs.scoreDocs[docs.scoreDocs.length - 1];
for (ScoreDoc scoreDoc : docs.scoreDocs) {
Document = searcher.doc(scoreDoc.doc, fields));
}
您确定正在查找要使用
术语删除的文档吗?尝试对其运行搜索,如:TopDocs=indexsearch.search(newtermquery(term),10)代码>,并确保结果符合预期。示例正确适用于数据操作。但是垃圾(lucene以前的段文件)没有被收集。我使用IndexSearcher.search()
&&IndexSearcher.searchAfter()
-重新编写了示例,现在旧段已被正确清理。也许这是正确的方法。