Redis实践:网站搜索的热搜词

news/2024/5/20 12:29:23/文章来源:https://blog.csdn.net/itcodexy/article/details/109574038

来源:Catcher8

www.cnblogs.com/catcher1994/p/5877262.html

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

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

 

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

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

技术说明 
.NET Core网站嘛,你懂的。有事没事用Core写写Demo,免得跟不上发展的脚步。
Redis存储搜索词,用了主从的模式,主写从读
Jquery-ui主要是用了里面的autocomplete

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

下面开始正题:

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

public IActionResult Index(){//keysIList<string> keys = new List<string>(){"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"};//initRandom random = new Random();var tran = _redis.GetTransaction();for (int i = 0; i < 1000000; i++){tran.SortedSetIncrementAsync(_searchKey, keys[random.Next(0, 70)], 1);}tran.ExecuteAsync();return View();}

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

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

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

public IActionResult GetHotKey(string key=""){if (string.IsNullOrEmpty(key)){//defaultvar res = _redis.ZRevRange(_searchKey, 0, 9);var list = (from i in res select i.ToString());return Json(list);}else{//by user inputvar res = _redis.ZRevRange(_searchKey, 0, -1);var list = (from i in res select i.ToString()).Where(x => x.Contains(key)).Take(10).ToList();return Json(list);}}

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

<div class="row"><div class="col-md-6 col-md-offset-4" style="padding-top:50px;"><input id="key" name="key" placeholder="search" class="form-control col-md-4"><button class="btn btn-primary" type="button" id="searchSubmit">Search</button><div id="result"></div></div>
</div>

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

@p scripts{<script type="text/javascript">$(function () {//show hot keyword$("#key").autocomplete({                source: function (request, response) {$.ajax({url: "@Url.Action("GetHotKey", "Auto")",dataType: "json",data: {key: request.term},success: function (data) {response(data);}});},});            </script>
}

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

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

[HttpPost]public IActionResult SetHotKey(string key){if (!string.IsNullOrWhiteSpace(key)){_redis.ZIncrby(_searchKey,key);//other //...return Json(new { code = "000", msg = "OK" });}else{return Json(new { code = "999", msg = "keyword can not be empty!" });}}

限制了用户不能搜索空关键字,在把这个关键字存储或者分数加一之后,就是展示我们的搜索的结果。这个搜索的结果一般是从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") {$("<p>search successful!</p>").appendTo("#result");} else {$("<p>"+data.msg+"</p>").appendTo("#result");}}});});

下面是效果图:

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

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

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

using AutoCompleteDemo.Common;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;namespace AutoCompleteDemo.Controllers
{public class AutoController : Controller{private readonly IRedis _redis;private readonly string _searchKey = "search";        public AutoController(IRedis redis){_redis = redis;}public IActionResult Index(){//keysIList<string> keys = new List<string>(){"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"};//initRandom random = new Random();var tran = _redis.GetTransaction();for (int i = 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)){//defaultvar res = _redis.ZRevRange(_searchKey, 0, 9);var list = (from i in res select i.ToString());return Json(list);}else{//by user inputvar res = _redis.ZRevRange(_searchKey, 0, -1);var list = (from i in res select i.ToString()).Where(x => x.Contains(key)).Take(10).ToList();return Json(list);}}[HttpPost]public IActionResult SetHotKey(string key){if (!string.IsNullOrWhiteSpace(key)){_redis.ZIncrby(_searchKey,key);//other //...return Json(new { code = "000", msg = "OK" });}else{return Json(new { code = "999", msg = "keyword can not be empty!" });}}}
}AutoController
@{ViewData["Title"] = "Auto Complete";
}
<div class="row"><div class="col-md-6 col-md-offset-4" style="padding-top:50px;"><input id="key" name="key" placeholder="search" class="form-control col-md-4"><button class="btn btn-primary" type="button" id="searchSubmit">Search</button><div id="result"></div></div>
</div>
@p scripts{<script type="text/javascript">$(function () {//show hot keyword$("#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") {$("<p>search successful!</p>").appendTo("#result");} else {$("<p>"+data.msg+"</p>").appendTo("#result");}}});});});</script>
}Index.cshtml

--完--

如果需要Redis视频,可以在公众号后台聊天框回复【Redis视频】,可以免费获取编程视频 。

Redis其它推荐阅读:

Redis 零基础入门视频教程

Linux 安装 Redis 图文教程

刚接触学Redis,看这一篇就够了!

再来聊聊Redis到底是什么?

说说 Redis 数据结构和常用命令

Redis最常见面试问题,附答案!

阿里巴巴官方 Redis 开发规范!

如何借助 Redis 实现秒杀系统?

史上最全 Redis 高可用解决方案总结

10 个正确使用 Redis 的技巧

Redis 分布式锁的正确实现方式

Redis 源码学习之 Redis 事务

详解Redis的内存淘汰策略

Redis 的各项功能,都解决了哪些问题?

为什么单线程的Redis却能支撑高并发?

Redis应用场景,实现功能 “附近的人”

超详细揭秘 Redis 持久化,建议收藏!

后端开发都应该掌握的Redis基础

Redis是如何实现点赞、取消点赞的?

如何用 Redis 做实时订阅推送的?

Redis 在百亿数据量中的使用技巧

Redis 主从复制以及主从复制原理

如何访问 Redis 中的海量数据?

一文深入了解Redis内存模型!

Redis常见的几种缓存模式

长按加入10W+朋友的IT圈

觉得内容还不错的话,给我点个“在看”呗

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_727102.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

架设高可用网站用多少台服务器,Nacos服务器高可用集群搭建

Nacos服务器高可用集群搭建Nacos服务器高可用集群搭建[var1]1.环境openjdk: 1.8.0_181nacos: 1.3.1 * nacos需使用最新版本才能兼容8.*版本的mysqlmysql: 8.0.19三台机器(至少需要三个或三个以上的nacos节点才能搭建集群)ip: 192.168.8.81192.168.8.82192.168.8.832.部署集群*在…

Scrapy使用Downloader Middleware设置代理访问网站

一、首先上网找到一个好用能用的代理 二、找到以后设置代理&#xff1a; win10打开控制面板里的internet选项里的局域网设置&#xff0c; 在这里设置勾选&#xff0c;设置好代理后&#xff0c;点击确定。代理设置完毕。 三、代码实现 middlewares.py class ProxyMiddlewar…

用 Python 清理收藏夹里已失效的网站

失效的书签们我们日常浏览网站的时候&#xff0c;时不时会遇到些新奇的东西&#xff08; 你懂的.jpg &#xff09;&#xff0c;于是我们就默默的点了个收藏或者加书签。然而当我们面对成百上千的书签和收藏夹的时候&#xff0c;总会头疼不已……尤其是昨天还在更新的程序设计博…

网站资源防盗链结构设计

标题索引 追溯原因 数据测试 防盗结构 追溯原因 一步一印&#xff0c;有印为证&#xff0c;网站资源防盗链老生常谈&#xff0c;但是如何才能确保网站资源如图片等特殊资源不被盗链&#xff1f;这不仅仅是运维人员所考虑的问题&#xff0c;更是开发人员必须控制并解决的一个问…

Python爬虫+Flask,带你创建个网站!

文化不分边界人&#xff0c;为什么要读书&#xff1f;举个例子:当看到天边飞鸟&#xff0c;你会说&#xff1a;“落霞与孤鹜齐飞&#xff0c;秋水共长天一色。”而不是&#xff1a;“卧靠&#xff0c;好多鸟。”;当你失恋时你低吟浅唱道&#xff1a;“人生若只如初见&#xff0…

jiathis:社交化数据分析 帮助网站提高流量

随着微博的兴起&#xff0c;社会化营销逐渐走进我们的生活&#xff0c;不管是杜蕾斯微博事件还是最近在小米大战360&#xff0c;都是在社会化平台上面进行&#xff0c;而 如何方便的将网站内 容分享至社会化媒体&#xff0c;&#xff0c;大部分博主会选择工具&#xff0c;但选择…

珍藏已久的OS学习网站,拿出来分享给大家!

平常经常看推荐各种资源教程的&#xff0c;感觉有很多文章稂莠不齐&#xff0c;这次我来推荐点硬核的网站&#xff0c;包你有收获。一般很少有人推荐操作系统的网站吧。。。。。。这几个网站来源于我平常的学习总结&#xff0c;也有一些是来源于网上优秀的回答&#xff0c;希望…

哪个云服务器网站不用备案,有不需要备案的云服务器

有不需要备案的云服务器 内容精选换一换不想看文字&#xff0c;请直接戳视频链接。可以不做备案吗&#xff1f;根据《互联网信息服务管理办法》等相关规定&#xff0c;使用中国大陆节点服务器开办的网站&#xff0c;必须先办理网站备案&#xff0c;备案成功并获取通信管理局下发…

吴翰清澄清:从没黑过阿里网站!

前几日吴翰清辟谣网络传闻的“黑入阿里网站”、“马云下死命令留他”、“500万年薪”等信息&#xff0c;称这些均是假新闻。吴翰清微博全文&#xff1a;“这是个假新闻&#xff01;请不要再消费我和阿里来赚流量了。我再澄清一次&#xff1a;1、我从没黑过阿里网站。2、宣传黑客…

idea 一直索引_长宁区360SEO优化服务,搜索引擎优化_上海持硕信息技术有限公司...

首页 > 新闻中心发布时间&#xff1a;2020-11-01 02:58:47 导读&#xff1a;上海持硕信息技术有限公司为您提供长宁区360SEO优化服务,搜索引擎优化的相关知识与详情&#xff1a; 在你的栏目页拥有较多的内容页时&#xff0c;就应该考虑相关推荐和指引性的链接导向&#xff0…

三年前红遍众筹网站,这款出自MIT的家庭机器人终于开卖了

本文来自AI新媒体量子位&#xff08;QbitAI&#xff09;图里这个产品你大概见过&#xff0c;但想不起来它的名字。 它是一个“家用社交机器人”&#xff0c;名叫Jibo&#xff0c;有黑白两色。现在说来&#xff0c;它的功能似乎和巨头标配的智能音箱有点重叠&#xff1a;能够作为…

建立网站需要什么条件_建立网站时需要了解的网站建设知识

网站建设的重点是最重要的。 根据不同客户的需求&#xff0c;此重要性具有不同的定义。 但是对于人们的直观定位而言&#xff0c;页面的美观度是一个不可忽视的重要因素。 网页设计彰显创造力。 许多人追求目标。 网页设计确实是网站建设中非常重要的一点&#xff0c;也是人们看…

python获取网站信息_关于python模拟登陆抓取网站信息

我想用requests实现在www.lu.com模拟登陆后抓取一些产品信息&#xff0c;通过chrome的抓包工具我抓到了登陆时的form data和header(变量header)&#xff0c;以及访问需要抓取的页面时的header(变量listheader),但运行完程序后我输入r.url发现返回的地址是https://list.lu.com/n…

怎么避免后台被搜索_企业网站seo关键词优化怎么做?

关键词没有排名一切皆无。企业网站seo关键词优化到位一切皆有&#xff0c;怎么做好企业网站的关键词排名是困扰大部分seo从业者的问题。搜索引擎是一套程序&#xff0c;会按照程序的设定来判断一个网站的排序结果&#xff0c;从这个角度来讲&#xff0c;任何网站的优化点都是一…

python隐藏手机号码程序_Python网站手机号码解密的一种方法

黄页88网站反爬措施对手机号进行了一些加密处理。这里介绍一下怎么解密手机号码的方法。首先&#xff0c;我们看一下网站显示的手机号是这样的&#xff1a;显示的手机号使用ctrl c复制粘贴后变成了这样&#xff1a;复制后的手机号码而实际上&#xff0c;用Python爬虫获取到的内…

为什么大型网站前端使用PHP,后台逻辑却用Java?

来自&#xff1a;知乎链接&#xff1a;https://www.zhihu.com/question/20314377黄良懿&#xff0c;做做架构&#xff0c;写写代码前两周参加完 ThinkInLamp 的 PHP 架构师大会&#xff0c;听鸟哥一上午的分享&#xff0c;感慨很多&#xff0c;PHP 业界虽然方向不明荒废了两三年…

作为程序员,我都逛了哪些技术网站?(收藏篇)

一、在线教程首先列出一些在线教程网站&#xff0c;这些在线教程网站通常都比较适合入门&#xff0c;可以作为开发学习路上的第一个阶梯&#xff0c;也可以作为工作中的在线文档。1、菜鸟教程地 址&#xff1a;https://www.runoob.com/简 介&#xff1a;在线教程网站&#xff0…

九度搜索引擎点击优化_企业网站为什么要做SEO优化

点击上方“蓝字”&#xff0c;发现更多精彩~~~随着互联网的发展&#xff0c;企业都意识到了网络营销的前景是多么广大&#xff0c;都想从中赚取高额的利润。想要做出名堂来就需要你的网站被搜索引擎所收录&#xff0c;也只有被收录后才有可能被用户看到你的网站&#xff0c;来的…

网站翻译功能

功能分两块&#xff1a;1、获取页面上要翻译的内容&#xff1b; 2、将内容从自定义的资源包中匹配&#xff1b; 我的网站翻译就是在创建html页面的时候&#xff0c;重写其中的一个方法&#xff0c; 第一步&#xff1a;获取页面上要翻译的内容&#xff1a; 在MVC中由这么一个类&…

CDN网站加速的工作流程

2019独角兽企业重金招聘Python工程师标准>>> CDN的全称是Content Delivery Network&#xff0c;即内容分发网络。 CDN的通俗理解就是网站加速&#xff0c;CPU负载均衡&#xff0c;可以解决跨运营商&#xff0c;跨地区&#xff0c;服务器负载能力过低&#xff0c;带宽…