Ho alcuni documenti memorizzati in un indice Lucene con un campo docId. Voglio ottenere tutti i docIds memorizzati nell'indice. C'è anche un problema. Il numero di documenti è di circa 300.000 quindi preferirei ottenere questo documento in blocchi di dimensioni 500. È possibile farlo?È possibile iterare attraverso i documenti memorizzati nell'Indice Lucene?
risposta
IndexReader reader = // create IndexReader
for (int i=0; i<reader.maxDoc(); i++) {
if (reader.isDeleted(i))
continue;
Document doc = reader.document(i);
String docId = doc.get("docId");
// do something with docId here...
}
I numeri di documento (o ID) saranno numeri successivi da 0 a IndexReader.maxDoc() - 1. Questi numeri non sono persistenti e sono validi solo per IndexReader aperto. Si potrebbe verificare se il documento viene eliminato con IndexReader.isDeleted (int documentNumber) Metodo
Lucene 4
Bits liveDocs = MultiFields.getLiveDocs(reader);
for (int i=0; i<reader.maxDoc(); i++) {
if (liveDocs != null && !liveDocs.get(i))
continue;
Document doc = reader.document(i);
}
See Lucene-2600 in questa pagina per ulteriori informazioni: https://lucene.apache.org/core/4_0_0/MIGRATE.html
Questo è stato ripristinato da un altro utente ma l'editor originale era corretto, liveDocs può essere nullo – bcoughlan
Se usi .document (i) come negli esempi precedenti e salti i documenti cancellati fai attenzione se usi questo metodo per impaginare i risultati. i.e .: hai un elenco di 10 documenti/per pagina e devi procurarti i documenti. per pagina 6. Il tuo input potrebbe essere qualcosa del tipo: offset = 60, count = 10 (documenti da 60 a 70).
IndexReader reader = // create IndexReader
for (int i=offset; i<offset + 10; i++) {
if (reader.isDeleted(i))
continue;
Document doc = reader.document(i);
String docId = doc.get("docId");
}
Si avrà alcuni problemi con quelli eliminati perché non si dovrebbe iniziare da offset = 60, ma da offset = 60 + il numero di documenti eliminati che compaiono prima 60.
Un'alternativa che ho trovato è qualcosa del genere:
is = getIndexSearcher(); //new IndexSearcher(indexReader)
//get all results without any conditions attached.
Term term = new Term([[any mandatory field name]], "*");
Query query = new WildcardQuery(term);
topCollector = TopScoreDocCollector.create([[int max hits to get]], true);
is.search(query, topCollector);
TopDocs topDocs = topCollector.topDocs(offset, count);
nota: sostituire il testo tra [[]] con i propri valori. Eseguito su grande indice con 1,5 milioni di voci e ottenuto 10 risultati casuali in meno di un secondo. Accetto è più lento ma almeno puoi ignorare i documenti cancellati se hai bisogno di paginazione.
c'è una classe query denominata MatchAllDocsQuery
, penso che possa essere utilizzato in questo caso:
Query query = new MatchAllDocsQuery();
TopDocs topDocs = getIndexSearcher.search(query, RESULT_LIMIT);
Cosa succede se (reader.isDeleted (i)) manca? –
Senza il controllo isDeleted(), si genererebbero id per i documenti che erano stati precedentemente eliminati – bajafresh4life
Per completare il commento dall'alto. Le modifiche dell'indice vengono eseguite quando l'indice viene riaperto in modo che reader.isDeleted (i) sia necessario per garantire che i documenti siano validi. –