ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(七) 之 历史记录查询(时间,关键字,图片,文件),关键字高亮显示。
前言
上一篇讲解了如何自定义右键菜单,都是前端的内容,本篇内容就一个:查询。聊天历史纪录查询,在之前介绍查找好友的那篇博客里已经提到过 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(") > -,
isimg = mine.content.IndexOf("img[") > -
};
//在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 = , int pageSize = )
{
string st = starttime == null ? "" : starttime.Value.ToString("yyyy-MM-dd");
string et = endtime == null ? "" : endtime.Value.ToString("yyyy-MM-dd");
int from = (pageIndex - ) * 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/
ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(七) 之 历史记录查询(时间,关键字,图片,文件),关键字高亮显示。的更多相关文章
- ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室 实战系列
ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(零) 前言 http://www.cnblogs.com/panzi/p/5742089.html ASP.NET S ...
- ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(十二) 代码重构使用反射工厂解耦(一)缓存切换
前言 上一篇中,我们用了反射工厂来解除BLL和UI层耦合的问题.当然那是最简单的解决方法,再复杂一点的程序可能思路相同,但是在编程细节中需要考虑的就更多了,比如今天我在重构过程中遇到的问题.也是接下来 ...
- ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(零) 前言
前端时间听一个技术朋友说 LayIM 2.0 发布了,听到这个消息抓紧去官网看了一下.(http://layim.layui.com/)哎呀呀,还要购买授权[大家支持一下哦],果断买了企业版,喜欢钻研 ...
- ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(一) 之 基层数据搭建,让数据活起来(数据获取)
大家好,本篇是接上一篇 ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(零) 前言 ASP.NET SignalR WebIM系列第二篇.本篇会带领大家将 LayIM ...
- ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(二) 之 ChatServer搭建,连接服务器,以及注意事项。
上篇:ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(一) 之 基层数据搭建,让数据活起来(数据获取) 上一篇我们已经完成了初步界面的搭建工作,本篇将介绍IM的核心内容 ...
- ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(三) 之 实现单聊,群聊,发送图片,文件。
上篇讲解了如何搭建聊天服务器,以及客户端js怎么和layui的语法配合.服务器已经连接上了,那么聊天还会远吗? 进入正题,正如上一篇提到的我们用 Client.Group(groupId)的方法向客户 ...
- ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(四) 之 用户搜索(Elasticsearch),加好友流程(1)。
前面几篇基本已经实现了大部分即时通讯功能:聊天,群聊,发送文件,图片,消息.不过这些业务都是比较粗犷的.下面我们就把业务细化,之前用的是死数据,那我们就从加好友开始吧.加好友,首先你得知道你要加谁.L ...
- ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(五) 之 加好友,加群流程,消息管理和即时消息提示的实现
前言 前前一篇留了个小问题,在上一篇中忘了写了,就是关于LayIM已经封装好的上传文件或者图片的问题.对接好接口之后,如果上传速度慢,界面就会出现假死情况,虽然文件正在上传.于是我就简单做了个图标替代 ...
- ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(六) 之 Layim源码改造右键菜单--好友、组管理功能的实现。
前言 上一篇中讲解了加好友的流程,本篇将介绍好友管理,群组管理的右键菜单功能.当然由于菜单项目太多,都实现也得花费时间.只讲解一下我是如何从不知道怎么实现右键菜单到会自定义菜单的一个过程.另外呢,针对 ...
随机推荐
- webpack 教程 那些事儿06-gulp+webpack多页
本篇主要讲述用gulp+webpack构建多页应用 折腾到现在,项目还必须要进行,.vue文件必须要加载,也就是webpack必须引入.时间不多了,抛弃上个方案之后,只能牺牲热加载性能,用gulp+w ...
- Java Io(数据输入输出流)
Java Io 字节流中的DataInputStream 和 DataOutputStream,使用流更加方便,是流的一个扩展,更方便读取int, long,字符等类型数据. 事例代码如下: pack ...
- MySQL中的运算符
一.算法运算符: (A) 除法运算和模运算中,如果除数为0,非法,返回结果为NULL. 二.比较运算符: (A) 比较结果不确定是返回NULL. (B) 比较运算符可以用于比较数字.字符串和表达式.数 ...
- Linux下6种优秀的邮件传输代理
导读 在互联网上,邮件客户端向邮件服务器发送邮件然后将消息路由到正确的目的地(其他客户),其中邮件服务器使用的一个网络应用程序称为邮件传输代理(MTA). 最好的Linux邮件传输代理(MTAs) 邮 ...
- 11.2---字符串数组排序,删除变位词(CC150)
这道题主义的就是,要利用数组自带的sort函数. 此外,注意,利用hash来判断是否出现了. public static ArrayList<String> sortStrings(Str ...
- centos rpmforge repo
在这里找到合适的rpm包:http://pkgs.repoforge.org/rpmforge-release/ 下载 wget http://pkgs.repoforge.org/rpmforge- ...
- ndk学习17: jni之Java调用C&C++
一.Hello World 1. 定义函数原型 native关键字定义的函数即为jni函数 2.生成头文件 切换到src目录执行: (这个过程可以写脚本自动完成,比如自动拷贝到jni目录) javah ...
- ASP.NET Web API与Rest web api
ASP.NET Web API is a framework that makes it easy to build HTTP services that reach a broad range of ...
- python to be linux daemon
所需第三方库:python-daemon[https://pypi.python.org/pypi/python-daemon/] 使用方式: python linux_service.py star ...
- 1.把二元查找树转变成排序的双向链表[BST2DoubleLinkedList]
[题目]:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表.要求不能创建任何新的结点,只调整指针的指向. 比如将二元查找树 . 10 / \ 6 14 / \ / \ 4 8 12 16 转 ...