2016-07-30 12 views
2

私はlucene.netを使用してPDFファイルのインデックスを作成しています。約15000 pdfsを索引付けするのに40分、インデックス作成時間が長くなり、マイフォルダー内のpdfファイルの数が増えます。Lucene.netのインデックス作成速度を改善するには

  • 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(); 
     } 
+0

本当に 'writer.Optimize()'を呼び出す必要がありますか? 'writer.Commit()'で十分ではないでしょうか? – sisve

+0

返信@SimonSvenssonに感謝します。 Optimize()は必要ありません。 commit()によって試行され、パフォーマンスの向上はありません。 – Munavvar

+1

@Munavvar、変更を提案する前に、関連するメソッドのベンチマークを追加しようとしましたか?私は特にsearchFilesとExtractTextFromPdfメソッドに興味があります。私はあなたのコードがOKであると見なされるので、おそらく後者で問題が起こると信じています。さらに、PDFのサイズは何ですか?関連する文字数にインデックスと分析を制限することができます。 – AR1

答えて

0

インデックス部分は大丈夫です。 IndexWriterがスレッドセーフなので、Parallel.Foreach(MaxConcurrencyをコア数に設定し、この値で再生)を使用すると、マルチコアマシンを使用している場合に役立ちます。

しかし、あなたはGCをドキュメントタイプ検出部で狂わせてしまっています。すべてのToUpper()は痛いです。

  • lstFilesループの外側。それは試合「休憩」を見つけると、別の文字列

    string headerTestUpper = headerText.ToUpper(); 
    
  • を作成大文字でドキュメントの種類のループの

    var upperDocTypes = ltDocumentTypes.Select(x=>x.searchText.ToUpper()).ToList(); 
    
  • 外をltDocumentTypes .searchTextのコピーを作成します。これは、一致を見つけたらループを終了し、次のすべての反復を防止します。あなたはltDocumentTypesこのあなたに多くの改善が得られないかもしれないのサイズに応じて

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

(それはあなたに違いがあれば)最後の試合であるのに対し、もちろんこれは最初のマッチを意味します。

私はExtractTextFromPdfの場合は、最も高価な部分を賭けるでしょう。これをプロファイラーやStopWatchesで実行すると、コストはどこにあるのでしょうか。

関連する問題