首先,關於Lucene.Net 的文章已經不少了。我此次決定寫出來只是爲了練練手,雖然在別人看來沒什麼用,可是本身確實是手動實踐了一把。我我的以爲仍是有意義的。愛折騰、勇於實踐、纔能有所收穫,才能發現問題。不要怕本身寫的東西有問題,有問題才更好呢,可讓更多的人看見,提意見的固然是好,鄙視的……我也接受,給本身 動力去思考。javascript
想讓本身時刻保持着這種程序員-->代碼心態、人都是帶有惰性的,一旦玩起來 呵呵...css
相信你們對於LuceneNet 並不陌生了,園子裏面的文章不少。html
參考文章:java
http://www.cnblogs.com/birdshover/category/152283.htmljquery
http://www.cnblogs.com/psforever/archive/2011/10/06/2200019.htmlgit
界面是一個在線工具本身手動構的,能夠隨意的設計本身想要的界面。可是引用的css竟然不是Bootstrap的css,這點得注意。程序員
css樣式引用地址:http://www.bootcss.com/p/layoutit/css/bootstrap-combined.min.cssweb
http://www.bootcss.com/p/layoutit/css/layoutit.cssajax
在線工具地址:http://www.bootcss.com/p/layoutit/數據庫
數據庫大概8w條記錄,每次最多取出1W條查詢結果。正常人也不會看完這麼多的。
/// <summary> /// 得到搜索列表 /// </summary> /// <param name="keyword">關鍵字</param> /// <param name="pageSize"></param> /// <param name="currentPage">當前頁碼</param> /// <param name="count"></param> /// <param name="pageCount"></param> /// <param name="isLike">是否開啓模糊查詢</param> /// <returns></returns> public static List<StoreInfo> GetSearchList(string keyword, int pageSize, int currentPage, out int count, out int pageCount, bool isLike = false) { string keywords = keyword; //獲取用戶輸入關鍵字,以備設置高亮顯示 string strIndexPath = INDEX_STORE_PATH; List<StoreInfo> storeList = new List<StoreInfo>(); StoreInfo modelstore; pageCount = 0; count = 0; IndexSearcher search = null; try { search = new IndexSearcher(FSDirectory.Open(new System.IO.DirectoryInfo(strIndexPath)), true); } catch (Exception) { return null; } keyword = GetKeyWordsSplitBySpace(keyword, new PanGuTokenizer()); QueryParser titleQueryParser = new QueryParser(Lucene.Net.Util.Version.LUCENE_29, "body", new PanGuAnalyzer(true)); Query titleQuery = titleQueryParser.Parse(keyword); Query PrefixQuery_title = null; Query PrefixQuery_body = null; Query FuzzyQuery_Title = null; Query FuzzyQuery_body = null; Query WildcardQuery_title = null; Query WildcardQuery_body = null; if (isLike) { //以什麼開頭,輸入「ja」就能夠搜到包含java和javascript兩項結果了 PrefixQuery_title = new PrefixQuery(new Term("title", keywords)); PrefixQuery_body = new PrefixQuery(new Term("body", keywords)); //直接模糊匹配,假設你想搜索跟‘wuzza’類似的詞語,你可能獲得‘fuzzy’和‘wuzzy’。 FuzzyQuery_Title = new FuzzyQuery(new Term("title", keywords)); FuzzyQuery_body = new FuzzyQuery(new Term("body", keywords)); //通配符搜索 WildcardQuery_title = new WildcardQuery(new Term("title", keywords)); WildcardQuery_body = new WildcardQuery(new Term("body", keywords)); } //MultiFieldQueryParser BooleanQuery bq = new BooleanQuery(); bq.Add(titleQuery, BooleanClause.Occur.SHOULD);//表示條件關係爲「or」,BooleanClause.Occur.MUST表示「and」,BooleanClause.Occur.MUST_NOT表示「not」 if (isLike) { bq.Add(PrefixQuery_title, BooleanClause.Occur.SHOULD); bq.Add(PrefixQuery_body, BooleanClause.Occur.SHOULD); bq.Add(FuzzyQuery_Title, BooleanClause.Occur.SHOULD); bq.Add(FuzzyQuery_body, BooleanClause.Occur.SHOULD); bq.Add(WildcardQuery_title, BooleanClause.Occur.SHOULD); bq.Add(WildcardQuery_body, BooleanClause.Occur.SHOULD); } //建立一個結果收集器(收集結果最大數爲1000頁) TopScoreDocCollector collector = TopScoreDocCollector.create(pageSize * 1000, true); search.Search(bq, null, collector); TopDocs topDoc = collector.TopDocs(0, collector.GetTotalHits()); //搜索結果總數超出指定收集器大小,則擯棄 if (topDoc.totalHits > pageSize * 1000) count = pageSize * 1000; else count = topDoc.totalHits; int i = (currentPage - 1) * pageSize; #region Lucene.Net.Documents.Document docs; PanGu.HighLight.Highlighter highlighter; PanGu.HighLight.SimpleHTMLFormatter simpleHTMLFormatter; while (i < count && storeList.Count < pageSize) { modelstore = new StoreInfo(); docs = search.Doc(topDoc.scoreDocs[i].doc); try { string strTitle = docs.Get("title"); string strContent = docs.Get("body"); modelstore.Store_ID = Convert.ToInt32(docs.Get("id")); //高亮顯示設置 simpleHTMLFormatter = new PanGu.HighLight.SimpleHTMLFormatter("<span style=\"color:red;\">", "</span>"); highlighter = new PanGu.HighLight.Highlighter(simpleHTMLFormatter, new PanGu.Segment()); highlighter.FragmentSize = 200; //string GetBestFragment(keywords,content)方法會按照SimpleHTMLFormatter構造的格式對content中關鍵字進行高亮顯示 //但若是content中不包含keywords則會返回空值,故須要按照以下進行判斷 modelstore.Description = highlighter.GetBestFragment(keywords, strContent); if (string.IsNullOrEmpty(modelstore.Description)) { modelstore.Description = strContent; } modelstore.Store_Name = highlighter.GetBestFragment(keywords, strTitle); if (string.IsNullOrEmpty(modelstore.Store_Name)) { modelstore.Store_Name = strTitle; } } catch (Exception e) { continue; } finally { storeList.Add(modelstore); i++; } } #endregion search.Close(); pageCount = Convert.ToInt32(Math.Ceiling((double)collector.GetTotalHits() / pageSize)); return storeList; }
public ActionResult Index(string id = "", string kw = "", string isLike = "0", int pageIndex = 1) { string strKeyWorld = HttpDecode(id.Length == 0 ? kw : id); int pageSize = 10; int intCount = 0; int intPageCount = 0; bool _boolisLike = isLike == "1" ? true : false; List<StoreInfo> StoreInfoList = null; Stopwatch watch = new Stopwatch(); watch.Start();//調用方法開始計時 if (strKeyWorld.Length > 0) { StoreInfoList = LuceneNetUtils.GetSearchList(strKeyWorld, pageSize, pageIndex, out intCount, out intPageCount, _boolisLike); } watch.Stop();//調用方法計時結束 double time = watch.Elapsed.TotalSeconds;//總共花費的時間 ViewBag.time = time; ViewBag.kw = strKeyWorld; ViewBag.count = intCount; ViewBag.pageIndex = pageIndex; ViewBag.pageSize = pageSize; ViewBag.intPageCount = intPageCount; ViewBag._boolisLike = _boolisLike; return View(StoreInfoList); }
注意:ShowPageBarMvc是個頁碼條,在頁面當中用的時候必定要引用所在命名空間,或者添加webConfig
@using System.Web.Optimization; @using LX.EFOPT.Web.Main.CommonUtils; @using PagedList; @using PagedList.Mvc; @model List<LX.EFOPT.Web.Main.Models.StoreInfo> @{ Layout = "/Views/Shared/_LayoutLucene.cshtml"; } <script src="~/Js/jquery.ds.js"></script> <div class="container-fluid"> <div class="row-fluid"> <div class="span12"> <form class="form-search" action="/LuceneNet/index/" onsubmit="return _search.checkInput();"> <input class="input-medium search-query" id="inputKw" name="kw" value="@ViewBag.kw" type="text" /> <button id="btn_search" type="submit" class="btn">查找</button> <input type="checkbox" @(ViewBag._boolisLike ? "checked=checked":"") name="isLike" id="isLike" value="1" /><label for="isLike">是否開啓模糊查詢</label> <button id="btn_createIndex1" type="button" class="btn">建立索引-方式1</button> <button id="btn_createIndex2" type="button" class="btn">建立索引-方式2</button> </form> <div id="ajaxData" style="width:80%"> @{ if (Model != null) { <div style="margin-top:20px;"><p>得到約 @ViewBag.count 條結果,用時 @ViewBag.time 秒</p></div> foreach (var item in Model) { <div style="margin-top:20px;"> <h4>@item.Store_ID @Html.Raw(item.Store_Name)</h4> <p>@Html.Raw(item.Description)</p> <p><a class="btn" href="javascript:;">查看更多 »</a></p> </div> } int pageIndex = ViewBag.pageIndex; int pageSize = ViewBag.pageSize; int intCount = ViewBag.count; string kw = ViewBag.kw; string isLike = ViewBag._boolisLike ? "1":"0"; @Html.ShowPageBarMvc("/LuceneNet/Index", pageIndex, pageSize, intCount, "kw=" + kw + "&isLike=" + isLike) } else { <div style="margin-top:20px;"><h4>沒有找到你想要的數據</h4><p>能夠更改關鍵字試試</p></div> } } </div> </div> </div> </div> @Scripts.Render("/LuceneNet/js/Search.js")
/// <reference path="../../Js/jquery-1.7.1.min.js" /> /// <reference path="../../Js/jquery.ds.js" /> function LuceneNet() { this.$_inputKw = $("#inputKw"); this.$_btn_search = $("#btn_search"); this.$_btn_createIndex1 = $("#btn_createIndex1"); this.$_btn_createIndex2 = $("#btn_createIndex2"); } LuceneNet.prototype.init = function () { var _self = this; _self.$_btn_createIndex1.on("click", function () { _self.createIndex(1); }); _self.$_btn_createIndex2.on("click", function () { _self.createIndex(2); }); }; LuceneNet.prototype.checkInput = function () { _self = this; if (!_self.$_inputKw.val().length) { return false; } } LuceneNet.prototype.createIndex = function (_type) { _self = this; $.ds.tips.open("loading", "請稍後.."); $.ajax({ url: "/LuceneNet/CreateIndex", type: "get", dataType: "json", data: { type: _type }, contentType: "application/x-www-form-urlencoded; charset=utf-8", success: function (data) { $.ds.tips.close(); } }); } LuceneNet.prototype.Search = function () { _self = this; $.ajax({ url: "/", type: "get", dataType: "json", contentType: "application/x-www-form-urlencoded; charset=utf-8", data: { kw: decodeURI(_self.$_inputKw.val()) }, success: function (data) { } }); }; var _search = new LuceneNet(); _search.init();
下一篇將繼續折騰添加索引和刪除索引,和數據庫保持同步。
源代碼只是我在公司測試的一個項目,比較雜,沒有辦法所有提供下載。可是我會把代碼上傳到git或者是網盤
謝謝。