• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    使用Lucene.NET实现站内搜索

    导入Lucene.NET 开发包

    Lucene 是apache软件基金会一个开放源代码的全文检索引擎工具包,是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎。Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎。Lucene.Net 是 .NET 版的Lucene。

    你可以在这里下载到最新的Lucene.NET

    创建索引、更新索引、删除索引

    搜索,根据索引查找

    IndexHelper 添加、更新、删除索引

    using System;
    using Lucene.Net.Store;
    using Lucene.Net.Index;
    using Lucene.Net.Analysis.PanGu;
    using Lucene.Net.Documents;
    
    namespace BLL
    {
      class IndexHelper
      {
        /// summary>
        /// 日志小助手
        /// /summary>
        static Common.LogHelper logger = new Common.LogHelper(typeof(SearchBLL));
        /// summary>
        /// 索引保存的位置,保存在配置文件中从配置文件读取
        /// /summary>
        static string indexPath = Common.ConfigurationHelper.AppSettingMapPath("IndexPath");
        
        /// summary>
        /// 创建索引文件或更新索引文件
        /// /summary>
        /// param name="item">索引信息/param>
        public static void CreateIndex(Model.HelperModel.IndexFileHelper item)
        {
          try
          {
            //索引存储库
            FSDirectory directory = FSDirectory.Open(new System.IO.DirectoryInfo(indexPath), new NativeFSLockFactory());
            //判断索引是否存在
            bool isUpdate = IndexReader.IndexExists(directory);
            if (isUpdate)
            {
              //如果索引目录被锁定(比如索引过程中程序异常退出),则首先解锁
              if (IndexWriter.IsLocked(directory))
              {
                //解锁索引库
                IndexWriter.Unlock(directory);
              }
            }
            //创建IndexWriter对象,添加索引
            IndexWriter writer = new IndexWriter(directory, new PanGuAnalyzer(), !isUpdate, Lucene.Net.Index.IndexWriter.MaxFieldLength.UNLIMITED);
            //获取新闻 title部分
            string title = item.FileTitle;
            //获取新闻主内容
            string body = item.FileContent;
            //为避免重复索引,所以先删除number=i的记录,再重新添加
            //尤其是更新的话,更是必须要先删除之前的索引
            writer.DeleteDocuments(new Term("id", item.FileName));
            //创建索引文件 Document
            Document document = new Document();
            //只有对需要全文检索的字段才ANALYZED
            //添加id字段
            document.Add(new Field("id", item.FileName, Field.Store.YES, Field.Index.NOT_ANALYZED));
            //添加title字段
            document.Add(new Field("title", title, Field.Store.YES, Field.Index.NOT_ANALYZED));
            //添加body字段
            document.Add(new Field("body", body, Field.Store.YES, Field.Index.ANALYZED, Lucene.Net.Documents.Field.TermVector.WITH_POSITIONS_OFFSETS));
            //添加url字段
            document.Add(new Field("url", item.FilePath, Field.Store.YES, Field.Index.NOT_ANALYZED));
            //写入索引库
            writer.AddDocument(document);
            //关闭资源
            writer.Close();
            //不要忘了Close,否则索引结果搜不到
            directory.Close();
            //记录日志
            logger.Debug(String.Format("索引{0}创建成功",item.FileName));
          }
          catch (SystemException ex)
          {
            //记录错误日志
            logger.Error(ex);
            throw;
          }
          catch (Exception ex)
          {
            //记录错误日志
            logger.Error(ex);
            throw;
          }
        }
    
        /// summary>
        /// 根据id删除相应索引
        /// /summary>
        /// param name="guid">要删除的索引id/param>
        public static void DeleteIndex(string guid)
        {
          try
          {
            ////索引存储库
            FSDirectory directory = FSDirectory.Open(new System.IO.DirectoryInfo(indexPath), new NativeFSLockFactory());
            //判断索引库是否存在索引
            bool isUpdate = IndexReader.IndexExists(directory);
            if (isUpdate)
            {
              //如果索引目录被锁定(比如索引过程中程序异常退出),则首先解锁
              if (IndexWriter.IsLocked(directory))
              {
                IndexWriter.Unlock(directory);
              }
            }
            IndexWriter writer = new IndexWriter(directory, new PanGuAnalyzer(), !isUpdate, Lucene.Net.Index.IndexWriter.MaxFieldLength.UNLIMITED);
            //删除索引文件
            writer.DeleteDocuments(new Term("id", guid));
            writer.Close();
            directory.Close();//不要忘了Close,否则索引结果搜不到
            logger.Debug(String.Format("删除索引{0}成功", guid));
          }
          catch (Exception ex)
          {
            //记录日志
            logger.Error(ex);
            //抛出异常
            throw;
          }
        }
      }
    }

    Search 通过查找索引实现搜索

    using Lucene.Net.Analysis;
    using Lucene.Net.Analysis.PanGu;
    using Lucene.Net.Documents;
    using Lucene.Net.Index;
    using Lucene.Net.Search;
    using Lucene.Net.Store;
    using Model.HelperModel;
    using System;
    using System.Collections.Generic;
    
    namespace BLL
    {
      public static class SearchBLL
      {
        //一个类中可能会有多处输出到日志,多处需要记录日志,常将logger做成static 静态变量
        /// summary>
        /// 日志助手
        /// /summary>
        static Common.LogHelper logger = new Common.LogHelper(typeof(SearchBLL));
        /// summary>
        /// 索引保存位置
        /// /summary>
        static string indexPath = Common.ConfigurationHelper.AppSettingMapPath("IndexPath");
        /// summary>
        /// 搜索
        /// /summary>
        /// param name="keywords">用户搜索的关键词/param>
        /// returns>返回搜索的结果/returns>
        public static ListSearchResult> Search(string keywords)
        {
          try
          {
            //索引存储库
            FSDirectory directory = FSDirectory.Open(new System.IO.DirectoryInfo(indexPath), new NoLockFactory());
            //创建IndexReader对象
            IndexReader reader = IndexReader.Open(directory, true);
            //创建IndexSearcher对象
            IndexSearcher searcher = new IndexSearcher(reader);
            //新建PhraseQuery 查询对象
            PhraseQuery query = new PhraseQuery();
            //把用户输入的关键词进行拆词
            foreach (string word in SplitWord(keywords))
            {
              //添加搜索关键词
              query.Add(new Term("body", word));
            }
            //设置分词间距为100字之内
            query.SetSlop(100);
            TopScoreDocCollector collector = TopScoreDocCollector.create(1000, true);
            //根据查询条件查询结果
            searcher.Search(query, null, collector);
            //搜索到的ScoreDoc结果
            ScoreDoc[] docs = collector.TopDocs(0, collector.GetTotalHits()).scoreDocs;
            //保存搜索结果的list
            ListSearchResult> listResult = new ListSearchResult>();
            for (int i = 0; i  docs.Length; i++)
            {
              //取到文档的编号(主键,这个是Lucene .net分配的)
              //检索结果中只有文档的id,如果要取Document,则需要Doc再去取
              //降低内容占用
              int docId = docs[i].doc;
              //根据id找Document
              Document doc = searcher.Doc(docId);
              string number = doc.Get("id");
              string title = doc.Get("title");
              string body = doc.Get("body");
              string url = doc.Get("url");
              //建立一个搜索结果对象
              SearchResult result = new SearchResult();
              result.Number = number;
              result.Title = title;
              result.BodyPreview = Preview(body, keywords);
              result.Url = url;
              //添加到结果列表
              listResult.Add(result);
            }
            if (listResult.Count == 0)
            {
              return null;
            }
            else
            {
              return listResult;
            }
          }
          catch (SystemException ex)
          {
            logger.Error(ex);
            return null;
          }
          catch (Exception ex)
          {
            logger.Error(ex);
            return null;
          }
        }
    
        /// summary>
        /// 获取内容预览
        /// /summary>
        /// param name="body">内容/param>
        /// param name="keyword">关键词/param>
        /// returns>/returns>
        private static string Preview(string body, string keyword)
        {
          //创建HTMLFormatter,参数为高亮单词的前后缀 
          PanGu.HighLight.SimpleHTMLFormatter simpleHTMLFormatter = new PanGu.HighLight.SimpleHTMLFormatter("font color=\"red\">", "/font>");
          //创建 Highlighter ,输入HTMLFormatter 和 盘古分词对象Semgent 
          PanGu.HighLight.Highlighter highlighter = new PanGu.HighLight.Highlighter(simpleHTMLFormatter, new PanGu.Segment());
          //设置每个摘要段的字符数 
          highlighter.FragmentSize = 100;
          //获取最匹配的摘要段 
          string bodyPreview = highlighter.GetBestFragment(keyword, body);
          return bodyPreview;
        }
    
        /// summary>
        /// 盘古分词,对用户输入的搜索关键词进行分词
        /// /summary>
        /// param name="str">用户输入的关键词/param>
        /// returns>分词之后的结果组成的数组/returns>
        private static string[] SplitWord(string str)
        {
          Liststring> list = new Liststring>();
          Analyzer analyzer = new PanGuAnalyzer();
          TokenStream tokenStream = analyzer.TokenStream("", new System.IO.StringReader(str));
          Lucene.Net.Analysis.Token token = null;
          while ((token = tokenStream.Next()) != null)
          {
            list.Add(token.TermText());
          }
          return list.ToArray();
        }
      }
    }

    SearchResult 模型

    namespace Model.HelperModel
    {
      public class SearchResult
      {
        public string Number { get; set; }
    
        public string Title { get; set; }
    
        public string BodyPreview { get; set; }
    
        public string Url { get; set; }
      }
    }

    以上所述就是本文的全部内容了,希望大家能够喜欢。

    您可能感兴趣的文章:
    • Lucene.Net实现搜索结果分类统计功能(中小型网站)
    • Java实现lucene搜索功能的方法(推荐)
    • 基于Lucene的Java搜索服务器Elasticsearch安装使用教程
    • 使用Java的Lucene搜索工具对检索结果进行分组和分页
    • 基于ASP.NET的lucene.net全文搜索实现步骤
    • 使用Lucene实现一个简单的布尔搜索功能
    上一篇:ASP.NET中集成百度编辑器UEditor
    下一篇:使用SWFUpload实现无刷新上传图片
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    使用Lucene.NET实现站内搜索 使用,Lucene.NET,实现,站内,