Ich habe einige Dokumente in einem Lucene-Index mit einem docId-Feld gespeichert. Ich möchte alle DocIds im Index gespeichert werden. Es gibt auch ein Problem. Die Anzahl der Dokumente beträgt ungefähr 300 000, also würde ich es vorziehen, diese Dokumente in Stücke der Größe 500 zu bringen. Ist das möglich?Ist es möglich, in Lucene Index gespeicherte Dokumente zu durchlaufen?
Antwort
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...
}
Dokumentennummern (oder IDs) sind Folgezahlen von 0 bis IndexReader.maxDoc() - 1. Diese Nummern sind nicht persistent und nur für geöffneten IndexReader gültig. Sie könnten prüfen, ob das Dokument mit IndexReader.isDeleted (int Document) -Methode
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 auf dieser Seite für Details gelöscht: https://lucene.apache.org/core/4_0_0/MIGRATE.html
Dies wurde von einem anderen Benutzer zurückgesetzt, aber der ursprüngliche Editor war korrekt. LiveDocs können null sein – bcoughlan
Wenn Sie .document (i) wie in den obigen Beispielen verwenden und gelöschte Dokumente überspringen, sollten Sie vorsichtig sein, wenn Sie diese Methode zum Paginieren von Ergebnissen verwenden. d. H .: Sie haben eine Liste mit 10 Dokumenten/pro Seite und Sie müssen die Dokumente abrufen. für Seite 6. Ihre Eingabe könnte etwa so aussehen: Offset = 60, Count = 10 (Dokumente von 60 bis 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");
}
Sie werden einige Probleme mit den gelöschten haben, weil Sie nicht von offset = 60 beginnen soll, aber von offset = 60 + die Anzahl der gelöschten Dokumente, die vor erscheinen 60.
Eine Alternative gefunden: ist etwas wie das:
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);
hinweis: ersetze text zwischen [[]] mit eigenen werten. Ließ dies auf großen Index mit 1,5 Millionen Einträge und bekam zufällige 10 Ergebnisse in weniger als einer Sekunde. Zustimmen ist langsamer, aber Sie können gelöschte Dokumente zumindest ignorieren, wenn Sie Seitenumbrüche benötigen.
Es wird eine Abfrage Klasse mit dem Namen MatchAllDocsQuery
, ich glaube, es kann in diesem Fall verwendet werden:
Query query = new MatchAllDocsQuery();
TopDocs topDocs = getIndexSearcher.search(query, RESULT_LIMIT);
Was passiert, wenn (reader.isDeleted (i)) fehlt? –
Ohne die isDeleted() - Prüfung würden Sie IDs für Dokumente ausgeben, die zuvor gelöscht wurden – bajafresh4life
Um einen Kommentar von oben abzuschließen. Indexänderungen werden beim erneuten Öffnen des Indexes festgelegt, daher ist reader.isDeleted (i) erforderlich, um die Gültigkeit der Dokumente zu gewährleisten. –