从零开始搭建.NET Core版搜索引擎(二)--简单项目示例

19 篇文章 7 订阅
11 篇文章 4 订阅

上一篇中实现的示例作为一个简单演示还行,但是作为通用方法使用就差的远了。本篇会对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接口的形式对外提供服务。

在这里插入图片描述


项目地址:https://github.com/ludewig/Muyan.Search

后续将对基础操作类进一步扩展…

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值