·您现在的位置: 云翼网络 >> 文章中心 >> 网站建设 >> 网站建设开发 >> ASP.NET网站开发 >> 使用Lucene.NET实现简单的站内搜索

使用Lucene.NET实现简单的站内搜索

作者:佚名      ASP.NET网站开发编辑:admin      更新时间:2022-07-23

使用Lucene.NET实现简单的站内搜索

使用Lucene.NET实现简单的站内搜索

  1. 导入Lucene.NET 开发包

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

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

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

  3. 搜索,根据索引查找

      1 using System;  2 using Lucene.Net.Store;  3 using Lucene.Net.Index;  4 using Lucene.Net.Analysis.PanGu;  5 using Lucene.Net.Documents;  6   7 namespace BLL  8 {  9     class IndexHelper 10     { 11         /// <summary> 12         /// 日志小助手 13         /// </summary> 14         static Common.LogHelper logger = new Common.LogHelper(typeof(SearchBLL)); 15         /// <summary> 16         /// 索引保存的位置,保存在配置文件中从配置文件读取 17         /// </summary> 18         static string indexPath = Common.ConfigurationHelper.AppSettingMapPath("IndexPath"); 19          20         /// <summary> 21         /// 创建索引文件或更新索引文件 22         /// </summary> 23         /// <param name="item">索引信息</param> 24         public static void CreateIndex(Model.HelperModel.IndexFileHelper item) 25         { 26             try 27             { 28                 //索引存储库 29                 FSDirectory directory = FSDirectory.Open(new System.IO.DirectoryInfo(indexPath), new NativeFSLockFactory()); 30                 //判断索引是否存在 31                 bool isUpdate = IndexReader.IndexExists(directory); 32                 if (isUpdate) 33                 { 34                     //如果索引目录被锁定(比如索引过程中程序异常退出),则首先解锁 35                     if (IndexWriter.IsLocked(directory)) 36                     { 37                         //解锁索引库 38                         IndexWriter.Unlock(directory); 39                     } 40                 } 41                 //创建IndexWriter对象,添加索引 42                 IndexWriter writer = new IndexWriter(directory, new PanGuAnalyzer(), !isUpdate, Lucene.Net.Index.IndexWriter.MaxFieldLength.UNLIMITED); 43                 //获取新闻 title部分 44                 string title = item.FileTitle; 45                 //获取新闻主内容 46                 string body = item.FileContent; 47                 //为避免重复索引,所以先删除number=i的记录,再重新添加 48                 //尤其是更新的话,更是必须要先删除之前的索引 49                 writer.DeleteDocuments(new Term("id", item.FileName)); 50                 //创建索引文件 Document 51                 Document document = new Document(); 52                 //只有对需要全文检索的字段才ANALYZED 53                 //添加id字段 54                 document.Add(new Field("id", item.FileName, Field.Store.YES, Field.Index.NOT_ANALYZED)); 55                 //添加title字段 56                 document.Add(new Field("title", title, Field.Store.YES, Field.Index.NOT_ANALYZED)); 57                 //添加body字段 58                 document.Add(new Field("body", body, Field.Store.YES, Field.Index.ANALYZED, Lucene.Net.Documents.Field.TermVector.WITH_POSITIONS_OFFSETS)); 59                 //添加url字段 60                 document.Add(new Field("url", item.FilePath, Field.Store.YES, Field.Index.NOT_ANALYZED)); 61                 //写入索引库 62                 writer.AddDocument(document); 63                 //关闭资源 64                 writer.Close(); 65                 //不要忘了Close,否则索引结果搜不到 66                 directory.Close(); 67                 //记录日志 68                 logger.Debug(String.Format("索引{0}创建成功",item.FileName)); 69             } 70             catch (SystemException ex) 71             { 72                 //记录错误日志 73                 logger.Error(ex); 74                 throw; 75             } 76             catch (Exception ex) 77             { 78                 //记录错误日志 79                 logger.Error(ex); 80                 throw; 81             } 82         } 83  84         /// <summary> 85         /// 根据id删除相应索引 86         /// </summary> 87         /// <param name="guid">要删除的索引id</param> 88         public static void DeleteIndex(string guid) 89         { 90             try 91             { 92                 ////索引存储库 93                 FSDirectory directory = FSDirectory.Open(new System.IO.DirectoryInfo(indexPath), new NativeFSLockFactory()); 94                 //判断索引库是否存在索引 95                 bool isUpdate = IndexReader.IndexExists(directory); 96                 if (isUpdate) 97                 { 98                     //如果索引目录被锁定(比如索引过程中程序异常退出),则首先解锁 99                     if (IndexWriter.IsLocked(directory))100                     {101                         IndexWriter.Unlock(directory);102                     }103                 }104                 IndexWriter writer = new IndexWriter(directory, new PanGuAnalyzer(), !isUpdate, Lucene.Net.Index.IndexWriter.MaxFieldLength.UNLIMITED);105                 //删除索引文件106                 writer.DeleteDocuments(new Term("id", guid));107                 writer.Close();108                 directory.Close();//不要忘了Close,否则索引结果搜不到109                 logger.Debug(String.Format("删除索引{0}成功", guid));110             }111             catch (Exception ex)112             {113                 //记录日志114                 logger.Error(ex);115                 //抛出异常116                 throw;117             }118         }119     }120 }
    IndexHelper 添加、更新、删除索引
      1 using Lucene.Net.Analysis;  2 using Lucene.Net.Analysis.PanGu;  3 using Lucene.Net.Documents;  4 using Lucene.Net.Index;  5 using Lucene.Net.Search;  6 using Lucene.Net.Store;  7 using Model.HelperModel;  8 using System;  9 using System.Collections.Generic; 10  11 namespace BLL 12 { 13     public static class SearchBLL 14     { 15         //一个类中可能会有多处输出到日志,多处需要记录日志,常将logger做成static 静态变量 16         /// <summary> 17         /// 日志助手 18         /// </summary> 19         static Common.LogHelper logger = new Common.LogHelper(typeof(SearchBLL)); 20         /// <summary> 21         /// 索引保存位置 22         /// </summary> 23         static string indexPath = Common.ConfigurationHelper.AppSettingMapPath("IndexPath"); 24         /// <summary> 25         /// 搜索 26         /// </summary> 27         /// <param name="keyWords">用户搜索的关键词</param> 28         /// <returns>返回搜索的结果</returns> 29         public static List<SearchResult> Search(string keywords) 30         { 31             try 32             { 33                 //索引存储库 34                 FSDirectory directory = FSDirectory.Open(new System.IO.DirectoryInfo(indexPath), new NoLockFactory()); 35                 //创建IndexReader对象 36                 IndexReader reader = IndexReader.Open(directory, true); 37                 //创建IndexSearcher对象 38                 IndexSearcher searcher = new IndexSearcher(reader); 39                 //新建PhraseQuery 查询对象 40                 PhraseQuery query = new PhraseQuery(); 41                 //把用户输入的关键词进行拆词 42                 foreach (string word in SplitWord(keywords)) 43                 { 44                     //添加搜索关键词 45                     query.Add(new Term("body", word)); 46                 } 47                 //设置分词间距为100字之内 48                 query.SetSlop(100); 49                 TopScoreDocCollector collector = TopScoreDocCollector.create(1000, true); 50