在前面的例子中,利用的都是直接在文件系统上建立索引,如 Lucene.Net.Store.Directory indexDir = FSDirectory.Open(new DirectoryInfo(@"F:\lucene_index"));
其中Directory是一个抽象类,具有多态性,这里用过FSDirectory.Open()静态方法实现了一个FSDirectory实例,并给Directory赋值。
当然Lucene.Net也提供了内存中的索引RAMDirectory,在内存中的索引要比文件中的索引要快得多。下面通过一个例子来说明,同时对10000个文档建立索引,其它条件都相同。s代码如下:
static void Main(string[] args)
{
//构造索引存放的路径,初始化一个FSFSDirectory对象
Lucene.Net.Store.Directory FSDir = FSDirectory.Open(new DirectoryInfo(@"F:\lucene_index"));
//构造一个RAMDirectory
Lucene.Net.Store.Directory ramdir = new RAMDirectory();
//构造一个索引器,以文件系统为目标
IndexWriter IWFS = new IndexWriter(FSDir, new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29), true, new IndexWriter.MaxFieldLength(10000));
//构造一个索引器,以内存为目标
IndexWriter IWRAM = new IndexWriter(ramdir, new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29), true, new IndexWriter.MaxFieldLength(10000));
Field bookname = new Field("filmname", "射雕英雄传", Field.Store.YES, Field.Index.ANALYZED);
//在FSDirectory对10000个Document建立索引,输出所花费的时间
DateTime FSStart = DateTime.Now;
for (int i = 0; i < 10000; i++)
{
Document doc = new Document();
doc.Add(bookname);//向文档中添加域
IWFS.AddDocument(doc);
}
//关闭索引写入,一定要记得,否则会写不进去
IWFS.Close();
Console.WriteLine(string.Format("以文件系统为目标的索引花费时间为:{0}",(DateTime.Now-FSStart).TotalMilliseconds.ToString()));
//在RAMDirectory对10000个Document建立索引,输出所花费的时间
DateTime RAMStart = DateTime.Now;
for (int i = 0; i < 10000; i++)
{
Document doc = new Document();
doc.Add(bookname);//向文档中添加域
IWRAM.AddDocument(doc);
}
//关闭索引写入,一定要记得,否则会写不进去
IWRAM.Close();
Console.WriteLine(string.Format("以内存系统为目标的索引花费时间为:{0}", (DateTime.Now - RAMStart).TotalMilliseconds.ToString()));
}
可以看到内存索引所花费的时间比文件系统要少。
因此当修改参数:mergeFactor、maxMergeDocs、maxBufferedDocs以达到性能最优的时候,如过仍想进一步提高索性操作的性能,就可以把RAMDirectory作为缓冲器,进一步提高性能。也就是把先把索引建在内存中,当索引建好后,在向文件系统的索引合并。这里提到了一个新的操作方法,即索引的合并问题。在上面的代码后面加上如下代码:
//构造索引存放的路径,初始化一个FSFSDirectory对象
Lucene.Net.Store.Directory FSDir = FSDirectory.Open(new DirectoryInfo(@"F:\lucene_index"));
//构造一个RAMDirectory
Lucene.Net.Store.Directory ramdir = new RAMDirectory();
//构造一个索引器,以文件系统为目标
IndexWriter IWFS = new IndexWriter(FSDir, new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29), true, new IndexWriter.MaxFieldLength(10000));
//构造一个索引器,以内存为目标
IndexWriter IWRAM = new IndexWriter(ramdir, new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29), true, new IndexWriter.MaxFieldLength(10000));
Field bookname = new Field("filmname", "射雕英雄传", Field.Store.YES, Field.Index.ANALYZED);
//在FSDirectory对10000个Document建立索引,输出所花费的时间
DateTime FSStart = DateTime.Now;
for (int i = 0; i < 10000; i++)
{
Document doc = new Document();
doc.Add(bookname);//向文档中添加域
IWFS.AddDocument(doc);
}
Console.WriteLine(string.Format("以文件系统为目标的索引花费时间为:{0}",(DateTime.Now-FSStart).TotalMilliseconds.ToString()));
//在RAMDirectory对10000个Document建立索引,输出所花费的时间
DateTime RAMStart = DateTime.Now;
for (int i = 0; i < 10000; i++)
{
Document doc = new Document();
doc.Add(bookname);//向文档中添加域
IWRAM.AddDocument(doc);
}
//关闭索引写入
IWRAM.Close();
Console.WriteLine(string.Format("以内存系统为目标的索引花费时间为:{0}", (DateTime.Now - RAMStart).TotalMilliseconds.ToString()));
//合并索引
IWFS.AddIndexesNoOptimize(new Lucene.Net.Store.Directory[]{ramdir});
IWFS.Optimize();
//关闭磁盘索引器
IWFS.Close();
这里主要是调用了函数AddIndexesNoOptimize来实现。
根据以上思路,可以创建一个多线程的索引程序,每个线程都基于RAMDirectory创建索引,然后在合并。
如果是多磁盘系统,也可以单独对两块磁盘进行并行化索引。