使用Lucene.NET实现简单的站内搜索
-
导入Lucene.NET 开发包
Lucene 是apache软件基金会一个开放源代码的全文检索引擎工具包,是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎。Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎。Lucene.Net 是 .NET 版的Lucene。
你可以在这里下载到最新的Lucene.NET
-
创建索引、更新索引、删除索引
-
搜索,根据索引查找IndexHelper 添加、更新、删除索引
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 }