2010-07-21 2 views
7

Ich schrieb eine kleine Schleife, die 10.000 Dokumente in den IndexWriter hinzugefügt und es dauerte für immer, es zu tun.Lucene IndexWriter langsam, um Dokumente hinzuzufügen

Gibt es eine andere Möglichkeit, große Mengen von Dokumenten zu indizieren?

Ich frage, denn wenn es live geht, muss es 15.000 Datensätze laden.

Die andere Frage ist, wie verhindere ich, dass alle Datensätze erneut geladen werden müssen, wenn die Webanwendung neu gestartet wird?

bearbeiten

Hier ist der Code i verwendet wird;

for (int t = 0; t < 10000; t++){ 
    doc = new Document(); 
    text = "Value" + t.toString(); 
    doc.Add(new Field("Value", text, Field.Store.YES, Field.Index.TOKENIZED)); 
    iwriter.AddDocument(doc); 
}; 

bearbeiten 2

 Analyzer analyzer = new StandardAnalyzer(); 
     Directory directory = new RAMDirectory(); 

     IndexWriter iwriter = new IndexWriter(directory, analyzer, true); 

     iwriter.SetMaxFieldLength(25000); 

dann der Code die Dokumente hinzufügen, dann;

 iwriter.Close(); 
+1

Wie lange war für immer? –

+0

dauerte es etwa 2,5 bis 3 Minuten. Ist das zu erwarten? – griegs

+0

Ich sollte hinzufügen, dass die Dokumente ein einzelnes Feld enthielten und dass das Feld "Wert" + t.toString() als Wert hatte. So sehr klein – griegs

Antwort

5

Nur Überprüfung, aber Sie haben nicht den Debugger angeschlossen, wenn Sie es ausgeführt haben Sie?

Dies beeinträchtigt die Leistung beim Hinzufügen von Dokumenten erheblich.

Auf meinem Rechner (Lucene 2.0.0.4):

mit Plattform Ziel x86 Bebaut:

  • Keine Debugger - 5,2 Sekunden

  • Debugger angebracht - 113,8 Sekunden

Errichtet mit Plattformziel x64:

  • Keine Debugger - 6,0 Sekunden

  • Debugger angebracht - 171,4 Sekunden

Raute Beispiel des Sparens und einen Index zu und von einem RAMDirectory Laden:

const int DocumentCount = 10 * 1000; 
const string IndexFilePath = @"X:\Temp\tmp.idx"; 

Analyzer analyzer = new StandardAnalyzer(); 
Directory ramDirectory = new RAMDirectory(); 

IndexWriter indexWriter = new IndexWriter(ramDirectory, analyzer, true); 

for (int i = 0; i < DocumentCount; i++) 
{ 
    Document doc = new Document(); 
    string text = "Value" + i; 
    doc.Add(new Field("Value", text, Field.Store.YES, Field.Index.TOKENIZED)); 
    indexWriter.AddDocument(doc); 
} 

indexWriter.Close(); 

//Save index 
FSDirectory fileDirectory = FSDirectory.GetDirectory(IndexFilePath, true); 
IndexWriter fileIndexWriter = new IndexWriter(fileDirectory, analyzer, true); 
fileIndexWriter.AddIndexes(new[] { ramDirectory }); 
fileIndexWriter.Close(); 

//Load index 
FSDirectory newFileDirectory = FSDirectory.GetDirectory(IndexFilePath, false); 
Directory newRamDirectory = new RAMDirectory(); 
IndexWriter newIndexWriter = new IndexWriter(newRamDirectory, analyzer, true); 
newIndexWriter.AddIndexes(new[] { newFileDirectory }); 

Console.WriteLine("New index writer document count:{0}.", newIndexWriter.DocCount()); 
+0

+1, danke dafür werde ich heute Abend schauen. Ich vermute, dass es der Debugger ist, jetzt, wo Sie es erwähnen. danke für deine hilfe – griegs

+0

danke für deine hilfe. Ich bin nicht ganz bei den tollen Zeiten, die du bist. meins ist bei 16 Sekunden, was akzeptabel ist, denke ich. Ich denke, es liegt jetzt an meiner Hardwear. – griegs

10

Sie sollte dies tun, um die beste Leistung zu erzielen.auf meinem Rechner habe ich die Indizierung 1000 Dokument in 1 Sekunde

1) Sie sollten (Dokument wiederverwenden, Feld) nicht jedes Mal, wenn Sie fügen Sie ein Dokument wie diese

private static void IndexingThread(object contextObj) 
{ 
    Range<int> range = (Range<int>)contextObj; 
    Document newDoc = new Document(); 
    newDoc.Add(new Field("title", "", Field.Store.NO, Field.Index.ANALYZED)); 
    newDoc.Add(new Field("body", "", Field.Store.NO, Field.Index.ANALYZED)); 
    newDoc.Add(new Field("newsdate", "", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS)); 
    newDoc.Add(new Field("id", "", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS)); 

    for (int counter = range.Start; counter <= range.End; counter++) 
    { 
     newDoc.GetField("title").SetValue(Entities[counter].Title); 
     newDoc.GetField("body").SetValue(Entities[counter].Body); 
     newDoc.GetField("newsdate").SetValue(Entities[counter].NewsDate); 
     newDoc.GetField("id").SetValue(Entities[counter].ID.ToString()); 

     writer.AddDocument(newDoc); 
    } 
} 

Danach Erstellen Sie Threading verwenden könnten und brechen Sie Ihre große Sammlung in kleinere, und für jeden Abschnitt zum Beispiel den obigen Code verwenden, wenn Sie 10.000 Dokument haben Sie 10 Gewinde mit Threadpool erstellen und füttern jeden Abschnitt ein Thread für die Indizierung

Dann gewinnen Sie die beste Leistung.

+0

+1 @Ehsan, vielen Dank dafür. Ich werde es heute ausprobieren. – griegs