我正在使用lucene.net索引我的pdf文件。索引15000 pdfs 大约需要40分钟,索引时间会随着我文件夹中pdf文件数量的增加而增加。
我正在使用最新版本的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 :(得分: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进行检测将是您的成本所在。