利用Lucene.NET怎么實(shí)現(xiàn)一個(gè)站內(nèi)搜索功能?針對這個(gè)問題,這篇文章詳細(xì)介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問題的小伙伴找到更簡單易行的方法。
創(chuàng)新互聯(lián)公司長期為近1000家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為合肥企業(yè)提供專業(yè)的成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作、外貿(mào)網(wǎng)站建設(shè),合肥網(wǎng)站改版等技術(shù)服務(wù)。擁有十載豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開發(fā)。導(dǎo)入Lucene.NET 開發(fā)包
Lucene 是apache軟件基金會一個(gè)開放源代碼的全文檢索引擎工具包,是一個(gè)全文檢索引擎的架構(gòu),提供了完整的查詢引擎和索引引擎,部分文本分析引擎。Lucene的目的是為軟件開發(fā)人員提供一個(gè)簡單易用的工具包,以方便的在目標(biāo)系統(tǒng)中實(shí)現(xiàn)全文檢索的功能,或者是以此為基礎(chǔ)建立起完整的全文檢索引擎。Lucene.Net 是 .NET 版的Lucene。
你可以在這里下載到新的Lucene.NET
創(chuàng)建索引、更新索引、刪除索引
搜索,根據(jù)索引查找
IndexHelper 添加、更新、刪除索引
using System; using Lucene.Net.Store; using Lucene.Net.Index; using Lucene.Net.Analysis.PanGu; using Lucene.Net.Documents; namespace BLL { class IndexHelper { ////// 日志小助手 /// static Common.LogHelper logger = new Common.LogHelper(typeof(SearchBLL)); ////// 索引保存的位置,保存在配置文件中從配置文件讀取 /// static string indexPath = Common.ConfigurationHelper.AppSettingMapPath("IndexPath"); ////// 創(chuàng)建索引文件或更新索引文件 /// /// 索引信息 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); } } //創(chuàng)建IndexWriter對象,添加索引 IndexWriter writer = new IndexWriter(directory, new PanGuAnalyzer(), !isUpdate, Lucene.Net.Index.IndexWriter.MaxFieldLength.UNLIMITED); //獲取新聞 title部分 string title = item.FileTitle; //獲取新聞主內(nèi)容 string body = item.FileContent; //為避免重復(fù)索引,所以先刪除number=i的記錄,再重新添加 //尤其是更新的話,更是必須要先刪除之前的索引 writer.DeleteDocuments(new Term("id", item.FileName)); //創(chuàng)建索引文件 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); //關(guān)閉資源 writer.Close(); //不要忘了Close,否則索引結(jié)果搜不到 directory.Close(); //記錄日志 logger.Debug(String.Format("索引{0}創(chuàng)建成功",item.FileName)); } catch (SystemException ex) { //記錄錯(cuò)誤日志 logger.Error(ex); throw; } catch (Exception ex) { //記錄錯(cuò)誤日志 logger.Error(ex); throw; } } ////// 根據(jù)id刪除相應(yīng)索引 /// /// 要?jiǎng)h除的索引id 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,否則索引結(jié)果搜不到 logger.Debug(String.Format("刪除索引{0}成功", guid)); } catch (Exception ex) { //記錄日志 logger.Error(ex); //拋出異常 throw; } } } }
Search 通過查找索引實(shí)現(xiàn)搜索
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 { //一個(gè)類中可能會有多處輸出到日志,多處需要記錄日志,常將logger做成static 靜態(tài)變量 ////// 日志助手 /// static Common.LogHelper logger = new Common.LogHelper(typeof(SearchBLL)); ////// 索引保存位置 /// static string indexPath = Common.ConfigurationHelper.AppSettingMapPath("IndexPath"); ////// 搜索 /// /// 用戶搜索的關(guān)鍵詞 ///返回搜索的結(jié)果 public static ListSearch(string keywords) { try { //索引存儲庫 FSDirectory directory = FSDirectory.Open(new System.IO.DirectoryInfo(indexPath), new NoLockFactory()); //創(chuàng)建IndexReader對象 IndexReader reader = IndexReader.Open(directory, true); //創(chuàng)建IndexSearcher對象 IndexSearcher searcher = new IndexSearcher(reader); //新建PhraseQuery 查詢對象 PhraseQuery query = new PhraseQuery(); //把用戶輸入的關(guān)鍵詞進(jìn)行拆詞 foreach (string word in SplitWord(keywords)) { //添加搜索關(guān)鍵詞 query.Add(new Term("body", word)); } //設(shè)置分詞間距為100字之內(nèi) query.SetSlop(100); TopScoreDocCollector collector = TopScoreDocCollector.create(1000, true); //根據(jù)查詢條件查詢結(jié)果 searcher.Search(query, null, collector); //搜索到的ScoreDoc結(jié)果 ScoreDoc[] docs = collector.TopDocs(0, collector.GetTotalHits()).scoreDocs; //保存搜索結(jié)果的list List listResult = new List (); for (int i = 0; i < docs.Length; i++) { //取到文檔的編號(主鍵,這個(gè)是Lucene .net分配的) //檢索結(jié)果中只有文檔的id,如果要取Document,則需要Doc再去取 //降低內(nèi)容占用 int docId = docs[i].doc; //根據(jù)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"); //建立一個(gè)搜索結(jié)果對象 SearchResult result = new SearchResult(); result.Number = number; result.Title = title; result.BodyPreview = Preview(body, keywords); result.Url = url; //添加到結(jié)果列表 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; } } /// /// 獲取內(nèi)容預(yù)覽 /// /// 內(nèi)容 /// 關(guān)鍵詞 ///private static string Preview(string body, string keyword) { //創(chuàng)建HTMLFormatter,參數(shù)為高亮單詞的前后綴 PanGu.HighLight.SimpleHTMLFormatter simpleHTMLFormatter = new PanGu.HighLight.SimpleHTMLFormatter("", ""); //創(chuàng)建 Highlighter ,輸入HTMLFormatter 和 盤古分詞對象Semgent PanGu.HighLight.Highlighter highlighter = new PanGu.HighLight.Highlighter(simpleHTMLFormatter, new PanGu.Segment()); //設(shè)置每個(gè)摘要段的字符數(shù) highlighter.FragmentSize = 100; //獲取最匹配的摘要段 string bodyPreview = highlighter.GetBestFragment(keyword, body); return bodyPreview; } /// /// 盤古分詞,對用戶輸入的搜索關(guān)鍵詞進(jìn)行分詞 /// /// 用戶輸入的關(guān)鍵詞 ///分詞之后的結(jié)果組成的數(shù)組 private static string[] SplitWord(string str) { Listlist = new List (); 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; } } }
關(guān)于利用Lucene.NET怎么實(shí)現(xiàn)一個(gè)站內(nèi)搜索功能問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識。