2014-05-17 3 views
0

J'ai un code simple pour parcourir et mettre à jour des documents. L'index est trop grand - des millions de documents, 10-20gb. Ceci est un pseudo-code:Comment itérer et mettre à jour des documents sur des documents 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 a fonctionné correctement avec le lecteur, qu'il initialisés. Mais lié aux segments d'index du lecteur (fichiers) n'a pas été supprimé avant l'ouverture du lecteur, et la taille de l'index est doublée à chaque itération de mise à jour. Après la journée de travail, la taille de l'index est de téraoctets! Si vous fermez tous les lecteurs et écrit, et rouvrez les anciens segments d'index seront supprimés. Comment correctement itérer & mettre à jour des documents sans fuite de fichiers de disque?

J'utilise Java 1.7, Lucene 4.8

+0

Etes-vous sûr que vous trouvez des documents à supprimer avec 'term'? Essayez d'exécuter une recherche par rapport à cela, comme: 'TopDocs docs = indexSearcher.search (new TermQuery (term), 10);', et assurez-vous que les résultats sont ce que vous attendez. – femtoRgon

+0

Exemple fonctionne correctement pour la manipulation de données. Mais les ordures (fichiers de segments précédents lucene) ne sont pas collectées. – mitallast

+0

J'ai réécrit l'exemple en utilisant 'IndexSearcher.search()' && 'IndexSearcher.searchAfter()' - maintenant les anciens segments correctement nettoyés. Peut-être que c'est la bonne façon. – mitallast

Répondre

0

La meilleure solution que je trouve - utiliser IndexSearcher.search() & & IndexSearcher.searchAfter().

Quelque chose comme ceci:

// 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)); 
} 
Questions connexes