2014-05-17 101 views
0

我有用于迭代和更新文档的简单代码。索引太大 - 数百万个文档,10-20gb。 这是一个伪代码:如何通过lucene文档迭代和更新文档?

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与读写器工作正常,它初始化。但是与阅读器索引片段(文件)相关的内容在打开阅读器之前不会被删除,并且每次更新迭代的索引大小都会增加一倍。工作一天之后,索引大小就是千兆字节! 如果关闭所有阅读器并写入,并重新打开索引,则旧部分将被删除。 如何正确迭代&更新文件,无需磁盘文件泄漏?

我用java 1.7,Lucene的4.8

+0

你确定你正在寻找的文件删除与'term'?尝试针对它执行搜索,例如:'TopDocs docs = indexSearcher.search(新的TermQuery(term),10);',并确保结果符合您的期望。 – femtoRgon

+0

正确的数据操作示例。但是不收集垃圾(lucene前面的段文件)。 – mitallast

+0

我重写了使用IndexSearcher.search()的示例'&&'IndexSearcher.searchAfter()' - 现在正确地清理了旧的段。也许这是正确的方法。 – mitallast

回答

0

最好的解决办法,我觉得 - 用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)); 
}