0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Redis简单案例:网站搜索的热搜词

电子工程师 来源:lq 2018-12-31 11:50 次阅读

对于一个网站来说,无论是商城网站还是门户网站,搜索框都是有一个比较重要的地位,它的存在可以说是为了让用户更快、更方便的去找到自己想要的东西。对于经常逛这个网站的用户,当然也会想知道在这里比较“火”的东西是什么,这个时候我们搜索框上的热词就起作用了。其实我觉得这一块的完善会对这个网站带来许多益处。

可能现在比较普遍的做法是把这些相应的信息存到我们的关系型数据库中,如sql server 和 oracle。方便起见的话,可能每搜索一次就往表里插一次数据,用的时候要先统计数据,统计完后再排序,最后才展示。这种情况下,如果搜索量很大的话,表的膨胀速度就会非常快,如果sql没写好,查询的时候估计会。。相比Redis,同等条件下,Redis的速率肯定是会较优,毕竟是从内存中拿出来的。

下面我们就用.NET Core和StackExchange.Redis来做一下这个简单的案例。

案例用到的一些相关技术和说明:

开始正题之前,我们要确定用Redis中的那种数据结构,五种之中比较合适的应该是SortedSet,我们可以用成员来作为搜索词,成员分数来作为搜索词的搜索次数,这样就可以很方便的来操作相关的数据了。

下面开始正题:

我们在开始的时候需要初始化一下数据。这里就直接在第一次运行的时候初始化。用上流水线的技术,速度还是很可观的。初始化了70个搜索关键词(NBA球星),然后用随机数作为关键字的下标,去随机给这个关键字加1分。这个分数就是这个关键字被搜索的次数。下面来看看初始化的相关代码:

publicIActionResultIndex(){//keysIListkeys=newList(){"kobe","johnson","jabbar","west","o'neal","baylor","mccann","worthy","gasol","chamberlain","fisher","odom","bynum","horry","rambis","riley","clarkson","Williams","young","Russell","ingram","randle","nance","brown","deng","yi","ariza","artest","walton","vujacic","james","paul","curry","park","yao","kevin","wade","rose","popovich","leonard","aldridge","ginobili","duncan","lavine","rubio","garnett","wiggins","westbrook","durant","ibaka","nowitzki","pierce","crawford","love","smith","iguodala","barnes","green","thompson","harden","lillard","mccollum","lin","jackson","nash","stoudemire","whiteside","dragic","Howard","batum"};//initRandomrandom=newRandom();vartran=_redis.GetTransaction();for(inti=0;i< 1000000; i++)            {                tran.SortedSetIncrementAsync(_searchKey, keys[random.Next(0, 70)], 1);            }            tran.ExecuteAsync();            return View();        }

这里是在加载这个页面的时候就把这些热搜词存进Redis中,这样我们才能有数据来演示啊。这里还用到了一个非事务型的流水线。就是把要操作的指令存放到一个队列中,最后把这个队列扔到服务端去执行,这样就有效的减少了不必要的网络传输,同时也提高了执行速度。

好了,初始数据有了,下面要做的就是用户在搜索的时候,根据用户的输入去匹配搜索次数多的关键字,展示最Hot的10个,当然这个展示的个数是随我们定的,最后可以考虑把这个放到我们的配置文件中去,甚至是放到数据库中,

为的是灵活和方便维护。下面是我们在后台的处理逻辑:

publicIActionResultGetHotKey(stringkey=""){if(string.IsNullOrEmpty(key)){//defaultvarres=_redis.ZRevRange(_searchKey,0,9);varlist=(fromiinresselecti.ToString());returnJson(list);}else{//byuserinputvarres=_redis.ZRevRange(_searchKey,0,-1);varlist=(fromiinresselecti.ToString()).Where(x=>x.Contains(key)).Take(10).ToList();returnJson(list);}}

对于查询的处理是非常的简单的,用户不小心输入空格的时候就展示最热的10个关键词,如果用户有输入的话,就把关键词中包含用户输入的展示出来。那么我们在页面上要做些什么呢?下面就是我们演示用的搜索框。

Search

相应的js是写到 scripts 这个section中的,js的话是比较简单的就是用ajax去请求我们要展示的数据。更多的应该是jquery-ui的api问题,大家也可以换用自己比较熟悉的组件,举一反三即可。下面是autocomplete的api,如果有需要可以去看一下。

@sectionscripts{$(function(){//showhotkeyword$("#key").autocomplete({source:function(request,response){$.ajax({url:"@Url.Action("GetHotKey","Auto")",dataType:"json",data:{key:request.term},success:function(data){response(data);}});},});}

到这里,用户搜索前的操作,我们是做好了,下面先来看一下效果。

那么用户点击了搜索之后我们要做些什么处理呢?无论是新的关键字还是已有的关键字,我们都是要做处理的,当然redis中zincrby命令来处理这个是十分合适的,存在的就把分数加1,不存在就创建一个分数为1的成员。下面是搜索时的后台逻辑处理:

[HttpPost]publicIActionResultSetHotKey(stringkey){if(!string.IsNullOrWhiteSpace(key)){_redis.ZIncrby(_searchKey,key);//other//...returnJson(new{code="000",msg="OK"});}else{returnJson(new{code="999",msg="keywordcannotbeempty!"});}}

限制了用户不能搜索空关键字,在把这个关键字存储或者分数加一之后,就是展示我们的搜索的结果。这个搜索的结果一般是从solr等全文检索的地方查出来的,不是我们讲的重点,所以就忽略了。然后我们还要加一段js去处理我们搜索的时候应该做的操作。当然,都是些比较简单的操作。

//search$("#searchSubmit").click(function(){$.ajax({url:"@Url.Action("SetHotKey","Auto")",dataType:"json",type:"POST",data:{key:$("#key").val()},success:function(data){if(data.code=="000"){$("

searchsuccessful!

").appendTo("#result");}else{$("

"+data.msg+"

").appendTo("#result");}}});});

下面是效果图:

在演示的时候,我们搜索了“我爱你”和“我不信”,在Redis的客户端我们找出搜索次数最少的6个,然后就可以看到我们那两个关键字最的分数都是1。确定是刚插入的数据。

到这里,我们做的这个热搜词可以说是大功告成了。当然这可以说是最最最简单的一个雏形。我们还可以适当的添加一些东西让这个功能变得更加完善。比如我可以在搜索展示的时候显示一下搜索的次数等。

最后是完整的控制器和页面代码:

usingAutoCompleteDemo.Common;usingMicrosoft.AspNetCore.Mvc;usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;namespaceAutoCompleteDemo.Controllers{publicclassAutoController:Controller{privatereadonlyIRedis_redis;privatereadonlystring_searchKey="search";publicAutoController(IRedisredis){_redis=redis;}publicIActionResultIndex(){//keysIListkeys=newList(){"kobe","johnson","jabbar","west","o'neal","baylor","mccann","worthy","gasol","chamberlain","fisher","odom","bynum","horry","rambis","riley","clarkson","Williams","young","Russell","ingram","randle","nance","brown","deng","yi","ariza","artest","walton","vujacic","james","paul","curry","park","yao","kevin","wade","rose","popovich","leonard","aldridge","ginobili","duncan","lavine","rubio","garnett","wiggins","westbrook","durant","ibaka","nowitzki","pierce","crawford","love","smith","iguodala","barnes","green","thompson","harden","lillard","mccollum","lin","jackson","nash","stoudemire","whiteside","dragic","Howard","batum"};//initRandomrandom=newRandom();vartran=_redis.GetTransaction();for(inti=0;i< 2000000; i++)            {                tran.SortedSetIncrementAsync(_searchKey, keys[random.Next(0, 70)], 1);            }            tran.ExecuteAsync();            return View();        }        public IActionResult GetHotKey(string key="")        {            if (string.IsNullOrEmpty(key))            {//default                var res = _redis.ZRevRange(_searchKey, 0, 9);                var list = (from i in res select i.ToString());                return Json(list);            }            else            {//by user input                var res = _redis.ZRevRange(_searchKey, 0, -1);                var list = (from i in res select i.ToString()).Where(x =>x.Contains(key)).Take(10).ToList();returnJson(list);}}[HttpPost]publicIActionResultSetHotKey(stringkey){if(!string.IsNullOrWhiteSpace(key)){_redis.ZIncrby(_searchKey,key);//other//...returnJson(new{code="000",msg="OK"});}else{returnJson(new{code="999",msg="keywordcannotbeempty!"});}}}}AutoController@{ViewData["Title"]="AutoComplete";}Search@sectionscripts{$(function(){//showhotkeyword$("#key").autocomplete({source:function(request,response){$.ajax({url:"@Url.Action("GetHotKey","Auto")",dataType:"json",data:{key:request.term},success:function(data){response(data);}});},});//search$("#searchSubmit").click(function(){$.ajax({url:"@Url.Action("SetHotKey","Auto")",dataType:"json",type:"POST",data:{key:$("#key").val()},success:function(data){if(data.code=="000"){$("

searchsuccessful!

").appendTo("#result");}else{$("

"+data.msg+"

").appendTo("#result");}}});});});}Index.cshtml

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

原文标题:Redis 简单案例(一):网站搜索的热搜词

文章出处:【微信号:DBDevs,微信公众号:数据分析与开发】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    [分享]最强山寨版搜索引擎震惊世界-熊熊搜索

    3295901让笔者特别喜欢的就是首页的关键排名,虽然这是谷歌的创意,但是放在首页上,每次一打开就知道全世界在什么。而且边上就是最热门的新闻和天涯的贴,所以你只要看熊熊的首页,马上就可以了解整个互联网
    发表于 11-22 18:58

    网站建设 ☑网站推广 ☑关键优化 ☑百度地标 ☑欢迎...

    网站建设 ☑网站推广 ☑关键优化 ☑百度地标 ☑欢迎咨询QQ:2991704102
    发表于 03-15 16:13

    关于电子发烧友论坛帖子搜索的问题建议

    搜索帖子,应该是每一个电子发烧友的爱好,也是一种习惯。大家都希望通过搜索关键来寻找自己想要的帖子。但是经过我这么长时间的使用,发现我们这个网站
    发表于 07-23 11:28

    labview中的搜索蓝牙不到蓝牙

    已将蓝牙适配器插入电脑且已安装该蓝牙适配器的驱动,为啥通过蓝牙的搜索蓝牙设备函数不到蓝牙?
    发表于 01-14 15:48

    离线语音Snowboy唤醒语音识别

    离线语音Snowboy唤醒语音识别现在有非常广泛的应用场景,如手机的语音助手,智能音响(小爱,叮咚,天猫精灵...)等.语音识别一般包含三个阶段:唤醒,语音录入,识别和逻辑控制
    发表于 07-30 08:06

    如何使得redis中的数据不再有

    嵌入式Linux系统重启后如何使得redis中的数据不再有今天在工作中遇到一个问题:网页展示redis中的数据,然而再Linux系统重启后网页还能展示redis中的数据,感觉很奇怪,到网上
    发表于 11-05 08:50

    如何清除划搜索

    如何清除划搜索    Q:董师傅,我安装了一个叫做划搜索的工具,现在想卸载,可是它的属性是只读,删除时系统提示无
    发表于 02-25 10:42 521次阅读

    首推行业垂直搜索 专注电子商务信息

    首推行业垂直搜索 专注电子商务信息 3月5日消息,据番薯网表示,其图书搜索平台有望在3月份正式亮相,其将采用中的核心搜索技术。就近
    发表于 03-06 08:42 569次阅读

    基于盲GDH签名的无记忆模糊关键搜索

    在云计算中,用户在计算过程中的数据安全问题已经成为制约云计算发展的一个瓶颈。本文针对云计算中的加密搜索问题,提出一个有效的加密搜索方案。在搜索过程中,为保证用户的数据安全,用户需要隐藏搜索
    发表于 12-14 14:14 0次下载

    区块链已经超过了加密货币成为了最受欢迎的搜索

    区块链一在谷歌的搜索中出现的频率更高。事实上,从今年下半年的搜索频率来看,它一直都超过了“加密货币”这个。区块链在7月份第一次这么做了,根据谷歌的说法,从9月份开始,它就成为了一个
    发表于 11-08 11:49 583次阅读

    百度推无广告“简单搜索”网页版?官方回应:没有 未来会考虑

    针对近日传的无广告简单搜索网页版,今日,百度简单搜索APP官方回应称,注意到关于百度推出简单
    的头像 发表于 04-07 11:28 2604次阅读
    百度推无广告“<b class='flag-5'>简单</b><b class='flag-5'>搜索</b>”网页版?官方回应:没有 未来会考虑

    AI占据榜首位置 成为2019年最受网友关注的科技

    2019年的尾声,百度发布了百度沸点2019十大科技。这十大是基于网友全年搜索数据,只以搜索
    发表于 01-13 15:56 554次阅读

    谷歌发布“2020年全球榜”

    谷歌发布了“2020年全球榜”,从独特的视角解读今年人们关注的热点事件和社会趋势。热门搜索关键分别是Coronavirus、Election results、Kobe Bryan
    的头像 发表于 12-10 15:12 3071次阅读

    5月电子元器件

    本期前四品牌ST,NXP,ADI,MOLEX,品类包括MCU芯片,MOSFET,连接器,分立器件等。
    的头像 发表于 06-16 15:45 1571次阅读
    5月电子元器件<b class='flag-5'>热</b><b class='flag-5'>搜</b>榜

    Redis官方搜索引擎来了,性能炸裂!

    RediSearch 是一个 Redis 模块,为 Redis 提供查询、二级索引和全文搜索功能。
    的头像 发表于 02-21 10:01 2308次阅读
    <b class='flag-5'>Redis</b>官方<b class='flag-5'>搜索</b>引擎来了,性能炸裂!