Я записал маленький цикл, который добавил 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();
Просто проверяю, но у вас нет подключенного отладчика, когда вы его запускаете?
Это серьезно влияет на производительность при добавлении документов.
На моей машине (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());
Вы должны сделать это, чтобы получить максимальную производительность. на моей машине я индексирую 1000 документов за 1 секунду
1) Вам следует повторно использовать (Document, Field), не создавая каждый раз, когда вы добавляете такой документ
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);
}
}
После этого вы можете использовать потоки и разбить вашу большую коллекцию на меньшие, и используйте приведенный выше код для каждого раздела например, если у вас есть 10000 документов, вы можете создать 10 потоков с помощью ThreadPool и передать каждый раздел в один поток для индексации
Тогда вы получите максимальную производительность.