Lucene IndexWriter медленно добавляет документы - PullRequest
7 голосов
/ 21 июля 2010

Я написал небольшой цикл, который добавил 10 000 документов в IndexWriter, и на это ушло навсегда.

Есть ли другой способ индексировать большие объемы документов?

Я спрашиваю, потому что, когда он будет запущен, он должен загрузить 15 000 записей.

Другой вопрос: как предотвратить повторную загрузку всех записей при перезапуске веб-приложения?

Редактировать

Вот код, который я использовал;

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);
};

Редактировать 2

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

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

        iwriter.SetMaxFieldLength(25000);

затем код для добавления документов, затем;

        iwriter.Close();

Ответы [ 2 ]

10 голосов
/ 29 июля 2010

Вы должны сделать так, чтобы получить наилучшую производительность. на моей машине я индексирую 1000 документов за 1 секунду

1) Вы должны повторно использовать (Документ, Поле), не создавая каждый раз, когда вы добавляете такой документ

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);
     }
}

После этого вы можете использовать многопоточность и разбивать большую коллекцию на более мелкие и использовать приведенный выше код для каждого раздела например, если у вас есть 10 000 документов, вы можете создать 10 Thread с помощью ThreadPool и направить каждый раздел в одна нить для индексации

Тогда вы получите лучшую производительность.

5 голосов
/ 21 июля 2010

Просто проверяете, но у вас нет подключенного отладчика, когда вы его запускаете?

Это сильно влияет на производительность при добавлении документов.

На моем компьютере (Lucene 2.0.0.4):

Построен с целевой платформой x86:

  • Без отладчика - 5,2 секунды

  • Отладчик подключен - 113,8 секунды

Построен с целевой платформой x64:

  • Нет отладчика - 6,0 секунд

  • Отладчик подключен -171,4 секунды

Пример грубого сохранения и загрузки индекса в / из RAMDirectory:

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());
...