国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發(fā)設計 > 正文

MVC+MQ+WinServices+Lucene.Net Demo

2019-11-17 02:28:43
字體:
供稿:網(wǎng)友
MVC+MQ+WinServices+Lucene.Net Demo

前言:

我之前沒有接觸過Lucene.Net相關的知識,最近在園子里看到很多大神在分享這塊的內(nèi)容,深受啟發(fā)。秉著“實踐出真知”的精神,再結(jié)合公司項目的實際情況,有了寫一個Demo的想法,算是對自己能力的考驗吧。

功能描述:

1. 前臺網(wǎng)站把新增的索引項對象(標題、內(nèi)容)序列化后,發(fā)送給MQ

2. MQ接收到消息后先持久化,再推送給消息的消費者

3. 消息的消費者(WinServices)接收到消息后,反序列化成索引項對象,調(diào)用SearchEngine類庫的創(chuàng)建索引方法

4. 前臺網(wǎng)站調(diào)用SearchEngine類庫的查詢方法,并傳入用戶輸入的關鍵字,把查詢后匹配的結(jié)果顯示在View上

注:

1. 為了模擬多個用戶同時新增索引項對象,互聯(lián)網(wǎng)本身就是一個多線程的環(huán)境。這里使用了ActiveMQ的隊列模式(另外還有主題模式,主要用于消息廣播的場景),因為其內(nèi)部維護了一個先進先出的隊列,可以保證每次只能有一個消息被接收,所有其它待接收的都需要排隊等待。

2. 這里引入了分布式項目的思想,前臺網(wǎng)站只復制新增索引項和查詢,MQ負責消息的接收和推送,WinServices負責生成索引文件。

3. 因為還只是Demo,所以很多功能還不完善,離真正企業(yè)級應用還有很大的差距,目的只是想練練手,熟悉下相關的知識點。

流程圖:

架構(gòu)圖:

層次圖:

項目結(jié)構(gòu):

LuceneTest.Entity:定義索引項和查詢結(jié)果類的類庫

LuceneTest.MQ:封裝消息隊列(ActiveMQ)發(fā)送和接收功能的類庫

LuceneTest.Web:用于管理索引項和查詢的MVC工程

LuceneTest.WinService.Test:用于WinService測試的WinForm工程

LuceneTest.SearchEngine:封裝Lucene.Net的創(chuàng)建索引和根據(jù)關鍵字查詢的類庫

關鍵代碼片段:

 1         /// <summary> 2         /// 創(chuàng)建索引 3         /// </summary> 4         /// <param name="model"></param> 5         public void CreateIndex(IndexSet model) 6         { 7             //打開 索引文檔保存位置 8             var directory = FSDirectory.Open(new DirectoryInfo(this._indexPath), new NativeFSLockFactory()); 9             //IndexReader:對索引庫進行讀取的類10             var isExist = IndexReader.IndexExists(directory);11 12             if (isExist)13             {14                 //如果索引目錄被鎖定(比如索引過程中程序異常退出或另一進程在操作索引庫),則解鎖15                 if (IndexWriter.IsLocked(directory))16                     //手動解鎖17                     IndexWriter.Unlock(directory);18             }19 20             //創(chuàng)建向索引庫寫操作對象,IndexWriter(索引目錄,指定使用盤古分詞進行切詞,最大寫入長度限制)21             //補充:使用IndexWriter打開directory時會自動對索引庫文件上鎖22             var writer = new IndexWriter(directory, new PanGuAnalyzer(), !isExist, IndexWriter.MaxFieldLength.UNLIMITED);23             //新建文檔對象,一條記錄對應索引庫中的一個文檔24             var document = new Document();25 26             //向文檔中添加字段27             //所有字段的值都將以字符串類型保存,因為索引庫只存儲字符串類型數(shù)據(jù)28 29             //Field.Store:是否存儲原文:30             //Field.Store.YES:存儲原值(如顯示原內(nèi)容必須為YES),可以用document.Get取出原值31             //Field.Store.NO:不存儲原值32             //Field.Store.COMPRESS:壓縮存儲33 34             //Field.Index:是否創(chuàng)建索引:35             //Field.Index.NOT_ANALYZED:不創(chuàng)建索引 36             //Field.Index.ANALYZED:創(chuàng)建索引(利于檢索)37 38             //WITH_POSITIONS_OFFSETS:指示不僅保存分割后的詞,還保存詞之間的距離39             document.Add(new Field("title", model.Title, Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS));40             document.Add(new Field("content", model.Content, Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS));41 42             //文檔寫入索引庫43             writer.AddDocument(document);44 45             //會自動解鎖46             writer.Close();47             //不要忘了Close,否則索引結(jié)果搜不到48             directory.Close();49         }
        /// <summary>        /// 查詢        /// </summary>        /// <param name="keyWord"></param>        /// <returns></returns>        public List<SearchResult> Search(string keyWord)        {            var searchResultList = new List<SearchResult>();            //打開 索引文檔保存位置            var directory = FSDirectory.Open(new DirectoryInfo(this._indexPath), new NoLockFactory());            //IndexReader:對索引庫進行讀取的類            var reader = IndexReader.Open(directory, true);            //關鍵詞分詞            var words = this.SplitWords(keyWord);            //搜索條件            var query = new PhraseQuery();            foreach (var item in words)            {                query.Add(new Term("content", item));            }            //指定關鍵詞相隔最大距離            query.SetSlop(100);            //TopScoreDocCollector:存放查詢結(jié)果的容器            var collector = TopScoreDocCollector.create(1000, true);            //IndexReader:對索引庫進行查詢的類            var searcher = new IndexSearcher(reader);            //根據(jù)query查詢條件進行查詢,查詢結(jié)果放入collector容器            searcher.Search(query, null, collector);            //TopDocs:指定0到GetTotalHits(),即所有查詢結(jié)果中的文檔,如果TopDocs(20,10)則意味著獲取第20-30之間文檔內(nèi)容,達到分頁的效果            var docs = collector.TopDocs(0, collector.GetTotalHits()).scoreDocs;            foreach (var item in docs)            {                var searchResult = new SearchResult();                //得到查詢結(jié)果文檔的id(Lucene內(nèi)部分配的id)                var docId = item.doc;                //根據(jù)文檔id來獲得文檔對象Document                var doc = searcher.Doc(docId);                searchResult.Id = docId;                searchResult.Title = doc.Get("title");                //高亮顯示                searchResult.Content = this.HightLight(keyWord, doc.Get("content"));                searchResultList.Add(searchResult);            }            return searchResultList;        }

查詢頁面View

@{    ViewBag.Title = "Search";}<h2>Search List</h2>@using (Html.BeginForm("Search", "IndexMgr")){    <div>        關鍵字:    </div>    <div>        @Html.TextBox("keyWord")    </div>           <input type="submit" value="保存" />}@{    var list = this.ViewBag.SearchResultList;    if (list != null)    {        foreach (var item in list)        {    @Html.Raw("標題:" + item.Title)    <br />    @Html.Raw("內(nèi)容:" + item.Content)    <hr />        }    }}

注意事項:

1. 如果使用盤古分詞算法,以下文件的“復制到輸出目錄”需要選擇“如果較新則復制”

2. 本Demo的索引文件保存在WinServices的可執(zhí)行目錄(bin/Debug/IndexData)下面,所以前臺網(wǎng)站要查詢,需要配置索引文件的路徑。

運行效果圖:

1. 新增索引項

2. 查詢

參考文獻:

http://m.survivalescaperooms.com/jiekzou/p/4364780.html

http://m.survivalescaperooms.com/piziyimao/archive/2013/01/31/2887072.html


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 渑池县| 麻栗坡县| 巴彦县| 雷波县| 新和县| 阜南县| 息烽县| 合川市| 隆德县| 抚远县| 祁阳县| 香港| 普兰店市| 奎屯市| 永宁县| 兴安县| 东山县| 潞城市| 桂平市| 克山县| 濮阳县| 宁陕县| 义乌市| 河源市| 祁连县| 孟连| 西乌珠穆沁旗| 罗平县| 岳西县| 突泉县| 泰来县| 类乌齐县| 民和| 乡城县| 石台县| 北京市| 沧源| 蓝田县| 苏尼特左旗| 太保市| 湖北省|