235  
查询码:00000946
基于Lucene.Net构建.NET Core版搜索引擎(二)--基础方法
作者: 潘帅 于 2021年09月27日 发布在分类 / 人防组 / 人防后端 下,并于 2021年09月27日 编辑
Lucene.NET 搜索引擎

上一篇中实现的示例作为一个简单演示还行,但是作为通用方法使用就差的远了。本篇会对Lucene的基本操作进行完善,同时对公共方法进行提取,使其更适合在.NET Core项目中使用。


1.基本方法完善


1.1.删除索引


        #region 删除所有索引
        /// <summary>
        /// 删除所有索引
        /// </summary>
        /// <param name="route">路由</param>
        public void DeleteAllIndex(string route)
        {
            //创建索引操作器配置项,包含Lucene版本定义和Analyzer分析器定义。此处使用4.8版本和标准分析器。
            IndexWriterConfig config = new IndexWriterConfig(LuceneVersion.LUCENE_48, new StandardAnalyzer(LuceneVersion.LUCENE_48));
            //打开索引存储路径
            Lucene.Net.Store.Directory dir = FSDirectory.Open("Lucene/" + route);
            using (IndexWriter writer = new IndexWriter(dir, config))
            {
                IndexReader reader = DirectoryReader.Open(dir);
                writer.DeleteAll();
                writer.Commit();
            }
        }
        #endregion

        #region 删除索引
        /// <summary>
        /// 删除索引
        /// </summary>
        /// <param name="docId">文档Id</param>
        /// <param name="route">路由</param>
        public void DeleteIndex(int docId, string route)
        {
            //创建索引操作器配置项,包含Lucene版本定义和Analyzer分析器定义。此处使用4.8版本和标准分析器。
            IndexWriterConfig config = new IndexWriterConfig(LuceneVersion.LUCENE_48, new StandardAnalyzer(LuceneVersion.LUCENE_48));
            //打开索引存储路径
            Lucene.Net.Store.Directory dir = FSDirectory.Open("Lucene/" + route);
            using (IndexWriter writer = new IndexWriter(dir, config))
            {
                IndexReader reader = DirectoryReader.Open(dir);
                writer.TryDeleteDocument(reader, docId);
            }
        }
        #endregion



1.2.更新索引



        /// <summary>
        /// 更新索引
        /// </summary>
        /// <param name="doc">文档</param>
        /// <param name="dic">要更新的域</param>
        /// <param name="route">路由</param>
        public void UpdateIndex(Document doc, Dictionary<string, string> dic, string route)
        {
            //创建索引操作器配置项,包含Lucene版本定义和Analyzer分析器定义。此处使用4.8版本和标准分析器。
            IndexWriterConfig config = new IndexWriterConfig(LuceneVersion.LUCENE_48, new StandardAnalyzer(LuceneVersion.LUCENE_48));
            //打开索引存储路径
            Lucene.Net.Store.Directory dir = FSDirectory.Open("Lucene/" + route);
            using (IndexWriter writer=new IndexWriter(dir,config))
            {
                foreach (var term in dic)
                {
                    writer.UpdateDocument(new Term(term.Key, term.Value), doc);
                }
                writer.Flush(true,true);
                writer.Commit();
            }
        }



1.3.索引计数



        /// <summary>
        /// 索引计数
        /// </summary>
        /// <param name="route">路由</param>
        /// <returns></returns>
        public int CountIndex(string route)
        {
            //打开索引存储路径
            Lucene.Net.Store.Directory dir = FSDirectory.Open("Lucene/" + route);
            //实例化索引读取器
            using (Lucene.Net.Index.DirectoryReader reader = DirectoryReader.Open(dir))
            {
                return reader.NumDocs;
            }
        }



2.接口约定提取

在之前的示例中基本方法的调用是通过操作类实例化后实现的,为了提高操作类的通用化并为后续的扩展做准备,将基本方法提取为接口方法。


   public interface ISearchManager
    {
        /// <summary>
        /// 创建索引
        /// </summary>
        /// <param name="fields"></param>
        /// <param name="route"></param>
        void CreateIndex(Dictionary<string,string> fields,string route);

        /// <summary>
        /// 删除索引
        /// </summary>
        /// <param name="docId">文档</param>
        /// <param name="route">路由</param>
        void DeleteIndex(int docId,string route);

        /// <summary>
        /// 删除所有索引
        /// </summary>
        void DeleteAllIndex(string route);

        /// <summary>
        /// 更新索引
        /// </summary>
        /// <param name="doc">文档</param>
        /// <param name="dic">要更新的域</param>
        /// <param name="route">路由</param>
        void UpdateIndex(Document doc,Dictionary<string,string> dic, string route);

        /// <summary>
        /// 索引计数
        /// </summary>
        /// <param name="route">路由</param>
        /// <returns></returns>
        int CountIndex(string route);

        /// <summary>
        /// 关键词查询
        /// </summary>
        /// <param name="keyword"></param>
        /// <param name="field"></param>
        /// <param name="route"></param>
        /// <returns></returns>
        Dictionary<Document, float> SearchIndex(string keyword,string field,string route);
    }
将接口ISearchManager通过SearchManager类来实现。




public class SearchManager : ISearchManager
{
    /**实现代码**/
}



3.应用范围扩展

在.NET Core项目中,可以通过依赖注入的形式将接口ISearchManager和实现类SearchManager关联起来,在具体使用时直接通过接口方法就能操作。

3.1.依赖注入

在.NET Core项目的Startup启动类中进行注册。


 services.AddTransient<ISearchManager, SearchManager>();

3.2.应用实践

在业务逻辑类中通过构造函数进行依赖注入。

        private readonly ISearchManager _searchManager;

        public DataContentManager(ISearchManager searchManager)
        {
            _searchManager = searchManager;
        }

原有的演示示例可以改为

        public void AddDemo()
        {
            Dictionary<string, string> dic = new Dictionary<string, string>();
            dic.Add("Name", "南京工大建设监理咨询有限公司");
            dic.Add("Address", "南京市中山北路200号");
            _searchManager.CreateIndex(dic, "data");
        }

        public List<string> SearchDemo(string key, string field)
        {
            List<string> list = new List<string>();
            Dictionary<Document, float> docs = _searchManager.SearchIndex(key, field,_route);
            foreach (var doc in docs)
            {
                string tmp = string.Format("doc:{0},score:{1}", doc.Key.ToString(), doc.Value.ToString());
                list.Add(tmp);
            }
            return list;
        }
在此基础上可以应用到ASP.NET Core项目中,以WebAPI接口的形式对外提供服务。




 推荐知识

 历史版本

修改日期 修改人 备注
2021-09-27 12:21:52[当前版本] 潘帅 1.0

 附件

附件类型

PNGPNG

预览图

知识分享平台 -V 4.8.7 -wcp