zoukankan      html  css  js  c++  java
  • Lucene.Net学习四——通过内存索引进一步提高索引的性能

    在前面的例子中,利用的都是直接在文件系统上建立索引,如   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创建索引,然后在合并。

    如果是多磁盘系统,也可以单独对两块磁盘进行并行化索引。

      

  • 相关阅读:
    [bzoj 4553][Tjoi2016&Heoi2016]序列
    [bzoj 5143][Ynoi 2018]五彩斑斓的世界
    [bzoj 4939][Ynoi 2016]掉进兔子洞
    luogu_P3674 小清新人渣的本愿
    [bzoj 2809][Apio2012]dispatching
    [bzoj 3110][zjoi 2013]K大数查询
    Entity Framework技巧系列之九
    Entity Framework技巧系列之八
    Entity Framework技巧系列之七
    Entity Framework技巧系列之六
  • 原文地址:https://www.cnblogs.com/guoyuanwei/p/2426005.html
Copyright © 2011-2022 走看看