Lucene IndexWriter添加文档很慢

时间:2010-07-21 02:12:48

标签: c# lucene lucene.net

我编写了一个小循环,在IndexWriter中添加了10,000个文档,并且它一直都是这样做的。

是否有其他方法可以索引大量文档?

我问,因为当它上线时,它必须加载15,000条记录。

另一个问题是,当重新启动Web应用程序时,如何防止必须再次加载所有记录?

修改

这是我使用的代码;

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 个答案:

答案 0 :(得分:10)

你应该这样做以获得最佳表现。在我的机器上,我在1秒内索引1000个文件

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个文档,则可以使用ThreadPool创建10个Thread并将每个部分提供给 一个用于索引的线程

然后你将获得最佳表现。

答案 1 :(得分:5)

只是检查一下,但是当你运行它时,你还没有连接调试器吗?

这会严重影响添加文档时的性能。

在我的机器上(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());