2014-05-17 75 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)); 
}