IndexWriter和IndexSearcher Lucene.net的单例模式 [英] Singleton pattern for IndexWriter and IndexSearcher Lucene.net

查看:201
本文介绍了IndexWriter和IndexSearcher Lucene.net的单例模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Lucene.net 3.0.3.0 (目前是最新版本).我想知道使用 IndexWriter IndexSearcher 的单个实例在生产环境中是否是一个不错的选择(考虑到线程安全性).我在文档中读到,创建这些实例的新对象是一项昂贵的操作,并且在内部Lucene可以很好地处理并发请求.

I'm using Lucene.net 3.0.3.0(the latest version right now). I would like to know if using a single instance of IndexWriter and IndexSearcher is a good choice in production environment(considering thread safety). I read in the documentation that creating new objects of these instances is an expensive operation and internally lucene handles concurrent requests pretty well.

这对于在生产环境中使用lucene.net的人们来说是一个问题;请让我知道是否可以解决!

This is a question to the people who have used lucene.net in production environment; please let me know if this will work out!

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Lucene.Net.Search;
    using Lucene.Net.Store;
    using System.IO;

    using Directory = Lucene.Net.Store.Directory;
    using Version = Lucene.Net.Util.Version;
    using Lucene.Net.Index;
    using Lucene.Net.Analysis.Standard;
    using Lucene.Net.Analysis;

    namespace MXLuceneConsoleApp
    {
        /// <summary>
        /// This helper class applies a singleton pattern to create Searcher and Writer objects as it's recommended to create them only once.
        /// Also the searcher gets reinitialized, if any write happens.    
        /// </summary>
        public class MXLuceneIndexHelper
        {
            private static IndexSearcher _searcher;        
            private static Directory _directory;
            private static Lazy<IndexWriter> _writer = new Lazy<IndexWriter>(() => new IndexWriter(_directory, new StandardAnalyzer(Version.LUCENE_30), IndexWriter.MaxFieldLength.UNLIMITED));

            //this private constructor makes it a singleton now.
            private MXLuceneIndexHelper() { }

            //Static constructor, opening the directory once for all.
            static MXLuceneIndexHelper()
            {
                _directory = FSDirectory.Open(new DirectoryInfo(Environment.CurrentDirectory + "\\LuceneIndexDir"));
            }

            public static IndexSearcher IndexSearcher
            {
                get
                {
                    if (_searcher == null)
                    {
                        InitializeSearcher();
                    }
                    else if (!_searcher.IndexReader.IsCurrent())
                    {                    
                        //_searcher.IndexReader.Reopen(); 
                        //refreshing the underlying Reader above doesn't do the trick, so I'm reinitializing the Searcher.
                        _searcher.Dispose();
                        InitializeSearcher();
                    }

                    return _searcher;
                }
            }

            public static IndexWriter IndexWriter
            {
                get 
                {                
                    //_writer.SetRAMBufferSizeMB(30.0);
                    return _writer.Value; 
                }
            }

            private static void InitializeSearcher()
            {
                _searcher = new IndexSearcher(_directory, false);

            }
        }//End of class
    }

推荐答案

我的理解是每个索引只能有1个IndexWriter实例.默认情况下,Lucene中启用了内置锁定,以确保出现这种情况.至于单例模式,我认为您应该看看新的 Lazy .NET 4中的类.它免费处理所有锁定和null检查.

My understanding is that there should only ever be 1 instance of IndexWriter per index. There is built in locking that is enabled in Lucene by default to ensure this condition. As far as a singleton pattern, I think you should look at the new Lazy class in .NET 4. It handles all the locking and null checking for free.

对于IndexSearcher,您可以随意拥有任意数量的实例.但是,我认为,如果重新使用现有的搜索器,则可以提高性能.我可以从您的代码中得知,您知道重新打开现有搜索器要比创建新搜索器便宜得多.此外,搜索器中还内置了缓存功能,当您进行第一次搜索时便会启动该功能.您还可以实现IndexReaderWarmer来控制搜索器的预热时间(如第一次搜索之前).

As for IndexSearcher, you are free to have as many instances as you want. However, I think there are performance gains if you reuse the existing searcher. I can tell from your code that you know that reopening an existing searcher is much cheaper than creating a new one. Also there is built in caching in the searcher that is initilaized when you do the first search. You can also implement an IndexReaderWarmer to control when the searcher is warmed (like before the first search).

这篇关于IndexWriter和IndexSearcher Lucene.net的单例模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆