如何提高Lucene.net索引速度

时间:2016-07-30 06:06:02

标签: c# performance lucene lucene.net full-text-indexing

我正在使用lucene.net索引我的pdf文件。索引15000 pdfs 大约需要40分钟,索引时间会随着我文件夹中pdf文件数量的增加而增加。

  • 如何在lucene.net中提高索引速度?
  • 是否有其他索引服务具有快速索引性能?

我正在使用最新版本的lucene.net索引(Lucene.net 3.0.3)。

这是我的索引编码。

public void refreshIndexes() 
        {
            // Create Index Writer
            string strIndexDir = @"E:\LuceneTest\index";
            IndexWriter writer = new IndexWriter(Lucene.Net.Store.FSDirectory.Open(new System.IO.DirectoryInfo(strIndexDir)), new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29), true, IndexWriter.MaxFieldLength.UNLIMITED);

            // Find all files in root folder create index on them
            List<string> lstFiles = searchFiles(@"E:\LuceneTest\PDFs");
            foreach (string strFile in lstFiles)
            {
                Document doc = new Document();
                string FileName = System.IO.Path.GetFileNameWithoutExtension(strFile);
                string Text = ExtractTextFromPdf(strFile);
                string Path = strFile;
                string ModifiedDate = Convert.ToString(File.GetLastWriteTime(strFile));
                string DocumentType = string.Empty;
                string Vault = string.Empty;

                string headerText = Text.Substring(0, Text.Length < 150 ? Text.Length : 150);
                foreach (var docs in ltDocumentTypes)
                {
                    if (headerText.ToUpper().Contains(docs.searchText.ToUpper()))
                    {
                        DocumentType = docs.DocumentType;
                        Vault = docs.VaultName; ;
                    }
                }

                if (string.IsNullOrEmpty(DocumentType))
                {
                    DocumentType = "Default";
                    Vault = "Default";
                }

                doc.Add(new Field("filename", FileName, Field.Store.YES, Field.Index.ANALYZED));
                doc.Add(new Field("text", Text, Field.Store.YES, Field.Index.ANALYZED));
                doc.Add(new Field("path", Path, Field.Store.YES, Field.Index.NOT_ANALYZED));
                doc.Add(new Field("modifieddate", ModifiedDate, Field.Store.YES, Field.Index.ANALYZED));
                doc.Add(new Field("documenttype", DocumentType, Field.Store.YES, Field.Index.ANALYZED));
                doc.Add(new Field("vault", Vault, Field.Store.YES, Field.Index.ANALYZED));

                writer.AddDocument(doc);
            }
            writer.Optimize();
            writer.Dispose();
        }

1 个答案:

答案 0 :(得分:0)

索引部分看起来不错。请注意,IndexWriter是线程安全的,因此使用Parallel.Foreach(将MaxConcurrency设置为核心数。使用此值)可能会对您提供多核计算机上的帮助。

但是你使用文档类型检测部分让你的GC变得疯狂。所有的ToUpper()都很痛苦。

  • 在lstFiles循环之外。以大写

    创建ltDocumentTypes .searchText的副本
    var upperDocTypes = ltDocumentTypes.Select(x=>x.searchText.ToUpper()).ToList();
    
  • 在doc类型循环之外创建另一个字符串

    string headerTestUpper = headerText.ToUpper();
    
  • 当找到匹配时#34;中断&#34;。一旦找到匹配项就会退出循环并阻止所有后续迭代。当然这意味着先匹配,而你的最后匹配(如果这对你有所影响)

    string headerText = Text.Substring(0, Text.Length < 150 ? Text.Length : 150);
    foreach (var searchText in upperDocTypes)
    {
        if (headerTextUpper.Contains(searchText))
        {
            DocumentType = docs.DocumentType;
            Vault = docs.VaultName;
            break;
        }
    }
    

根据ltDocumentTypes的大小,这可能不会给你太多改进。

我敢打赌,如果ExtractTextFromPdf是最昂贵的部分。通过分析器运行或使用一些StopWatches进行检测将是您的成本所在。