在上一篇中,我們初步理解了索引的增刪改查基本操作。本文著重介紹一下常用的搜索,以及搜索結果的排序和分頁。本文的搜索主要是基于前一篇介紹的文本文件的索引,建議下載最后改進的demo對照著看閱讀本文,同時大家可以自己動手創建一些測試文本,然后建立索引并搜索試試看。
先從上一篇示例代碼中我們摘錄一段代碼看看搜索的簡單實現:
| 1234567891011121314151617181920212223 | PRivate TopDocs Search(string keyWord,string field){TopDocs docs = null;int n = 10;//最多返回多少個結果SetOutput(string.Format("正在檢索關鍵字:{0}", keyword));try{QueryParser parser = new QueryParser(field, new StandardAnalyzer());Query query = parser.Parse(keyword);//搜索內容 contents (用QueryParser.Parse方法實例化一個查詢)Stopwatch watch = new Stopwatch();watch.Start();docs = searcher.Search(query, (Filter)null, n); //獲取搜索結果watch.Stop();StringBuffer sb = "索引完成,共用時:" + watch.Elapsed.Hours + "時 " + watch.Elapsed.Minutes + "分 " + watch.Elapsed.Seconds + "秒 " + watch.Elapsed.Milliseconds + "毫秒";SetOutput(sb);}catch (Exception ex){SetOutput(ex.Message);docs = null;}return docs;} |
從上面代碼,我們不難看出,搜索需要用到IndexSearcher,Query,QueryParser和TopDocs(或者Hits)四個核心類:
1、 IndexSearcherIndexSearcher會打開索引文件,它不使用Lucene.Net的鎖,可以理解為只讀操作。它的Search方法是我們最常用的,該方法返回我們需要的結果。2、QueryParserQueryParser是Query的構造器,它的Parse方法會根據Analyzer構造一個合理的Query對象來應對搜索。
3、QueryQuery類作為查詢表達式的載體同樣至關重要,它有豐富的子類,讓我們可以應對多種變化的搜索需求,簡單來說,我們想到的常用搜索Lucene.Net幾乎已經都給我們實現了,你只要分辨應該使用那個類來搜索比較合理。
4、TopDocs(或者Hits)
這個類我們可以簡單把它理解成它就是我們要的搜索結果集,通過它我們可以知道記錄集合中的各個Document的詳細信息:
?| 12345678910111213141516171819202122232425262728293031 | /// <summary>/// 顯示搜索結果/// </summary>/// <param name="queryResult"></param>private void ShowFileSearchResult(TopDocs queryResult){if (queryResult == null || queryResult.totalHits == 0){SetOutput("Sorry,沒有搜索到你要的結果。");return;}int counter = 1;foreach (ScoreDoc sd in queryResult.scoreDocs){try{Document doc = searcher.Doc(sd.doc);string id = doc.Get("id");//獲取idstring fileName = doc.Get("filename");//獲取文件名string contents = doc.Get("contents");//獲取文件內容string result = string.Format("這是第{0}個搜索結果,Id為{1},文件名為:{2},文件內容為:{3}{4}", counter, id, fileName, Environment.NewLine, contents);SetOutput(result);}catch (Exception ex){SetOutput(ex.Message);}
|