前言
上一篇講解了如何自定義右鍵選單,都是前端的內容,本篇內容就一個:查詢。聊天曆史紀錄查詢,在之前介紹查詢好友的那篇部落格裡已經提到過 Elasticsearch,今天它又要上場了。對於Elasticsearch不感冒的同學呢,本篇可以不用看啦。
from baidu:
DEMO演示
隨便聊聊天:
圖片型別過濾
檔案型別過濾
關鍵字查詢
時間段查詢(截圖略)
實戰講解
layim 已經給我們提供了開啟歷史紀錄頁面的介面。不過查詢歷史紀錄頁面需要自己佈局。由於html+css不是我的強項,我就直接把聊天室的結構拿過去了。聊天曆史紀錄頁面上就一個ajax請求,還有資料繫結,這些都不多做介紹。主要是講一下後臺如何進行資料查詢和細節注意事項。主要還是講到了Elasticsearch,對於Elasticsearch不感興趣的小夥伴可以略過本篇。
首先呢,想要查詢歷史紀錄,要先儲存資料。那麼在之前的LayIMHub中的接受訊息方法中,我們已經把資料順便在ES中儲存一份。(例項程式碼如下)
//儲存訊息 Task.Run(() => { MessageFactory.CreateInstance(ChatMessageSaveType.SearchEngine).Send(message); });
ChatInfo chatInfo; var mine = message.mine;
//聊天記錄model chatInfo = new ChatInfo { addtime = message.addtime, avatar = mine.avatar, content = mine.content, nickname = mine.username, qq = mine.id, timespan = message.addtime.ToTimestamp(), roomid = message.roomid, isfile = mine.content.IndexOf("file(") > -1, isimg = mine.content.IndexOf("img[") > -1 };
//在es中,index是索引的意思,相當於資料庫中的表
bool result= es.Index(chatInfo); return new SendMessageResult(result);
於是,我們使用者聊天的時候,將資料就儲存到了ES當中,正如SQL Server做搜尋一樣,想用ES搜尋,它也需要儲存一份。我們開啟客戶端看一下資料,如果你也安裝了ES和head外掛,那麼瀏覽器輸入 127.0.0.1:9200/_plugin/head就可以看資料了。
那麼資料已經有了,我們看一下查詢條件。 1,關鍵字查詢 2,型別查詢 3,時間段查詢 4,聊天室id查詢(最基本,A和B聊天不能查詢A和C的歷史紀錄)
他們之間的查詢關係是and條件,如果用sql表示的話就是 select * from chathistory where roomid=1 and content like '%誅仙%' and 。。。
那麼我們就需要把SQL翻譯成ES的語法。最終結果是這樣的。
{ "query": { "filtered": { "filter": { "and": [ //and關係 { "query": { "match": { "roomid": "FRIEND_14895_14894" //根據聊天室id過濾 } } }, { "term": { "isimg": false //是否是img } }, { "range": { //range查詢 "addtime": { //查詢欄位是時間型別 "gt": "2016-08-16T00:00:00" //gt 是大於某個時間 lt 是小於某個時間 } } } ] } } }, "from": 0, //分頁 "size": 50, "sort": { //排序 "addtime": { "order": "asc" } }, "highlight": { //高亮 "fields": { "content": {} //content高亮顯示 } } }
核心查詢方法如下:(.NET客戶端用的PlainElastic.Net,他已經對構造查詢語句做了封裝,類似ORM,但是語法我用的太蹩腳了,於是只有自己拼“SQL”了)
public JsonResultModel SearchHistoryMsg(string groupId, DateTime? starttime = null, DateTime? endtime = null, string keyword = null, bool isfile = false, bool isimg = false, int pageIndex = 1, int pageSize = 20) { string st = starttime == null ? "" : starttime.Value.ToString("yyyy-MM-dd"); string et = endtime == null ? "" : endtime.Value.ToString("yyyy-MM-dd"); int from = (pageIndex - 1) * pageSize; //某個聊天組查詢 string queryGroup = "{\"query\": {\"match\": { \"roomid\": \"FRIEND_14895_14894\" }}}"; //關鍵字查詢 string queryKeyWord = "{ \"query\": {\"match_phrase\": {\"content\": {\"query\": \"" + keyword + "\",\"slop\": 0} } }}"; //是否圖片 查詢 string queryImg = "{ \"term\": {\"isimg\": true }}"; //是否包含檔案查詢 string queryFile = "{ \"term\": {\"isfile\": true }}"; //大於小於某個時間段查詢 string queryTimeRange = "{\"range\": {\"addtime\": { \"gt\": \""+st+"\",\"lt\": \""+et+"\" }} }"; //大於某個時間 string queryTimeRangeGt = "{\"range\": {\"addtime\": { \"gt\": \""+st+"\"}} }"; //小於某個時間 string queryTimeRangeLt = "{\"range\": {\"addtime\": { \"lt\": \"" + et + "\" }} }"; string queryAnd = queryGroup; if (starttime != null&&endtime!=null) { queryAnd += "," + queryTimeRange; } if (starttime != null) { queryAnd += "," + queryTimeRangeGt; } if (endtime != null) { queryAnd += "," + queryTimeRangeLt; } if (!string.IsNullOrEmpty(keyword)) { queryAnd += "," + queryKeyWord; } if (isfile) { queryAnd += "," + queryFile; } if (isimg) { queryAnd += "," + queryImg; } //最終查詢語句 string query = " {\"query\": {\"filtered\": {\"filter\": {\"and\": [" + queryAnd + "] }}},\"from\": " + from + ",\"size\": " + pageSize + ",\"sort\": {\"addtime\": { \"order\": \"asc\"}},\"highlight\": {\"fields\": { \"content\": {}} }}"; var result = eschat.QueryBayConditions(query); return JsonResultHelper.CreateJson(result, true); }
那麼,只要條件給對了,結果自然就是我們想要的結果了。
不過,搜尋也是會出現bug的,例如,如果輸入關鍵字img或者file,就會出現下面這種情況,因為資料庫裡存的就是那一串html,然後到介面上又做了相應的處理,這個情況就有點蛋疼了。
有同學會注意到 img旁邊有em標籤,其實這個就是關鍵字高亮的原因所在。好比,上邊的演示中,誅仙兩個字是高亮的,檢視原始碼,他們每個字都會有em標籤包含,那是因為ES在查詢過程中,你可以使用高亮功能,他會把符合條件的關鍵字給你加上特殊標籤,當然我們也可以自定義標籤,例如 b,i ,tag 都可以。然後給一個樣式,比如我這裡 em {color:red} 那麼高亮功能就出來了。
總結
本篇呢基本上都是圍繞Elasticsearch來講,由於屬於一些額外的功能,所以也沒講太細。搜尋功能用SQL或者MySQL或者其他的一些資料庫都能實現,主要是對接layim要注意,繫結的方式以及圖片檔案的html轉換等。
下篇預告:【中級】ASP.NET SignalR 與 LayIM2.0 配合輕鬆實現Web聊天室(八) 之 聊天室的小細節,你都注意到了嗎?
想要學習的小夥伴,可以關注我的部落格哦,我的QQ:645857874,Email:fanpan26@126.com
GitHub:https://github.com/fanpan26/LayIM_NetClient/