2017-12-20 5 views
1

Wie kann ich alle indizierten (aber nicht gespeicherten) Begriffe für einen großen Index in Lucene.Net abrufen?Wie erhalten Sie alle indizierten Begriffe aus einem großen Lucene.Net-Index?

Der Grund, warum ich das tue, ist, weil ich von Lucene.Net zu der neuesten Version von Apache Lucene umziehe, und das Indexformat hat sich mehrfach gegenüber den Versionen geändert. Ich migriere die Daten, indem ich die Begriffe lese und sie dann wieder auf das neue Format indiziere. Ich kenne das Lucene-Codecs-Paket, aber das bietet keine ausreichende Abwärtskompatibilität für das von Lucene.Net verwendete Format.

Es gibt ähnliche Fragen, z.B. Find list of terms indexed by Lucene

Das Problem mit dem obigen Ansatz ist jedoch, dass IndexReader.Terms liest jeden einzelnen Begriff aus dem Index und dies verursacht einen OutOfMemoryException auf großen Indizes.

Wie kann ich alle Begriffe aus einem großen Index vernünftig erhalten, ohne zu riskieren, dass der Arbeitsspeicher knapp wird?

Beispiel-Code (das wirft OutOfMemoryException auf dem Aufruf von reader.Terms(orderBy)):

var results = new List<string>(); 
var orderBy = new Term("MyField", string.Empty); 
using (var reader = IndexReader.Open(FSDirectory.Open(_indexPath), true)) 
using (var termEnum = reader.Terms(orderBy)) 
{ 
    for (var term = termEnum.Term; term != null; termEnum.Next(), term = termEnum.Term) 
    { 
     if (term.Field != "MyField") 
     { 
      break; 
     } 
     results.Add(term.Text); 
    } 
} 

Antwort

2

auf den Code der Suche, so scheint es der einzige Grund, warum Sie könnten in diesem Szenario über genügend Arbeitsspeicher ausgeführt ist, weil Sie alle schreiben die Begriffe in eine List<string>. Um zu vermeiden, dass nicht genügend Arbeitsspeicher zur Verfügung steht, sollten Sie stattdessen die Zeichenfolgen auf der Festplatte speichern.

var orderBy = new Term("MyField", string.Empty); 
using (var reader = IndexReader.Open(FSDirectory.Open(_indexPath), true)) 
using (var termEnum = reader.Terms(orderBy)) 
using (var stream = new FileStream("TheFile.txt", FileMode.Create, FileAccess.Write)) 
using (var writer = new StreamWriter(stream)) 
{ 
    for (var term = termEnum.Term; term != null; termEnum.Next(), term = termEnum.Term) 
    { 
     if (term.Field != "MyField") 
     { 
      break; 
     } 
     writer.WriteLine(term.Text); 
    } 
} 

Während diese Frage beantworten kann, die Tatsache, dass Sie mehrere Begriffe aus dem Index zu ziehen versuchen, als Sie für Speicher haben, ist ein Zeichen dafür, dass Sie die falsche Frage stellen. Ich schlage vor, dass Sie eine andere Frage stellen, die beispielhaft für die eigentliche Aufgabe steht, die Sie zu tun versuchen - wahrscheinlich gibt es eine bessere (effizientere) Möglichkeit, dies zu tun, als all diese Rohdaten aus dem Index zu lesen.

Verwandte Themen