Redis简单案例(一) 网站搜索的热搜词

时间:2022-01-21 00:27:35

  对于一个网站来说,无论是商城网站还是门户网站,搜索框都是有一个比较重要的地位,它的存在可以说是

为了让用户更快、更方便的去找到自己想要的东西。对于经常逛这个网站的用户,当然也会想知道在这里比较“火”

的东西是什么,这个时候我们搜索框上的热词就起作用了。其实我觉得这一块的完善会对这个网站带来许多益处。

  可能现在比较普遍的做法是把这些相应的信息存到我们的关系型数据库中,如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()
{
//keys
IList<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","west*","durant","ibaka",
"nowitzki","pierce","crawford","love","smith","iguodala","barnes","green","thompson","harden",
"lillard","mccollum","lin","jackson","nash","stoudemire","whiteside","dragic","Howard","batum"
}; //init
Random random = new Random();
var tran = _redis.GetTransaction();
for (int i = ; i < 1; i++)
{
tran.SortedSetIncrementAsync(_searchKey, keys[random.Next(, )], );
}
tran.ExecuteAsync(); return View();
}

  这里是在加载这个页面的时候就把这些热搜词存进Redis中,这样我们才能有数据来演示啊。这里还用到了一个

非事务型的流水线。就是把要操作的指令存放到一个队列中,最后把这个队列扔到服务端去执行,这样就有效的减少

了不必要的网络传输,同时也提高了执行速度。

  好了,初始数据有了,下面要做的就是用户在搜索的时候,根据用户的输入去匹配搜索次数多的关键字,展示最

Hot的10个,当然这个展示的个数是随我们定的,最后可以考虑把这个放到我们的配置文件中去,甚至是放到数据库中,

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

         public IActionResult GetHotKey(string key="")
{
if (string.IsNullOrEmpty(key))
{//default
var res = _redis.ZRevRange(_searchKey, , );
var list = (from i in res select i.ToString());
return Json(list);
}
else
{//by user input
var res = _redis.ZRevRange(_searchKey, , -);
var list = (from i in res select i.ToString()).Where(x => x.Contains(key)).Take().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 这个section中的,js的话是比较简单的就是用ajax去请求我们要展示的数据。更多的应该是

jquery-ui的api问题,大家也可以换用自己比较熟悉的组件,举一反三即可。下面是autocomplete的api  ,如果有需要可

以去看一下。

 @section 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简单案例(一) 网站搜索的热搜词

  那么用户点击了搜索之后我们要做些什么处理呢?无论是新的关键字还是已有的关键字,我们都是要做处理的,当然redis

中zincrby命令来处理这个是十分合适的,存在的就把分数加1,不存在就创建一个分数为1的成员。下面是搜索时的后台逻辑处理:

         [HttpPost]
public IActionResult SetHotKey(string key)
{
if (!string.IsNullOrWhiteSpace(key))
{
_redis.ZIncrby(_searchKey,key);
//other
//...
return Json(new { code = "", msg = "OK" });
}
else
{
return Json(new { code = "", 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简单案例(一) 网站搜索的热搜词

  在演示的时候,我们搜索了“我爱你”和“我不信”,在Redis的客户端我们找出搜索次数最少的6个,然后就可以看到我们那两

个关键字最的分数都是1。确定是刚插入的数据。

Redis简单案例(一) 网站搜索的热搜词

  到这里,我们做的这个热搜词可以说是大功告成了。当然这可以说是最最最简单的一个雏形。我们还可以适当的添加一些

东西让这个功能变得更加完善。比如我可以在搜索展示的时候显示一下搜索的次数等。

Redis简单案例(一) 网站搜索的热搜词

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

 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()
{
//keys
IList<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","west*","durant","ibaka",
"nowitzki","pierce","crawford","love","smith","iguodala","barnes","green","thompson","harden",
"lillard","mccollum","lin","jackson","nash","stoudemire","whiteside","dragic","Howard","batum"
}; //init
Random random = new Random();
var tran = _redis.GetTransaction();
for (int i = ; i < ; i++)
{
tran.SortedSetIncrementAsync(_searchKey, keys[random.Next(, )], );
}
tran.ExecuteAsync(); return View();
} public IActionResult GetHotKey(string key="")
{
if (string.IsNullOrEmpty(key))
{//default
var res = _redis.ZRevRange(_searchKey, , );
var list = (from i in res select i.ToString());
return Json(list);
}
else
{//by user input
var res = _redis.ZRevRange(_searchKey, , -);
var list = (from i in res select i.ToString()).Where(x => x.Contains(key)).Take().ToList();
return Json(list);
}
} [HttpPost]
public IActionResult SetHotKey(string key)
{
if (!string.IsNullOrWhiteSpace(key))
{
_redis.ZIncrby(_searchKey,key);
//other
//...
return Json(new { code = "", msg = "OK" });
}
else
{
return Json(new { code = "", 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>
@section 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简单案例(一) 网站搜索的热搜词的更多相关文章

  1. Redis简单案例&lpar;二&rpar; 网站最近的访问用户

    我们有时会在网站中看到最后的访问用户.最近的活跃用户等等诸如此类的一些信息.本文就以最后的访问用户为例, 用Redis来实现这个小功能.在这之前,我们可以先简单了解一下在oracle.sqlserve ...

  2. SpringDataRedis操作Redis简单案例

    Jedis Jedis是Redis官方推出的一款面向Java的客户端,提供了很多接口供Java语言调用.可以在Redis官网下载,当然还有一些开源爱好者提供的客户端,如Jredis.SRP等等,推荐使 ...

  3. SpringBoot基础学习(一) SpringBoot概念、简单案例实现、单元测试及热部署讲解

    SpringBoot概念 Spring优缺点分析 Spring优点 Spring是Java企业版(Java Enterprise Edition,JEE,也称J2EE)的轻量级代替品,无需开发重量级的 ...

  4. SparkStreaming实时日志分析--实时热搜词

    Overview 整个项目的整体架构如下: 关于SparkStreaming的部分: Flume传数据到SparkStreaming:为了简单使用的是push-based的方式.这种方式可能会丢失数据 ...

  5. 纯前端实现词云展示&plus;附微博热搜词云Demo代码

    前言 最近工作中做了几个数据可视化大屏项目,其中也有用到了词云展示,以前做词云都是用python库来生成图片显示的,这次用了纯前端的实现(Ctrl+V真好用),同时顺手做个微博热搜的词云然后记录一下~ ...

  6. Redis简单案例&lpar;四&rpar; Session的管理

    负载均衡,这应该是一个永恒的话题,也是一个十分重要的话题.毕竟当网站成长到一定程度,访问量自然也是会跟着增长,这个时候, 一般都会对其进行负载均衡等相应的调整.现如今最常见的应该就是使用Nginx来进 ...

  7. Redis简单案例&lpar;三&rpar; 连续登陆活动的简单实现

    连续登陆活动,或许大家都不会陌生,简单理解就是用户连续登陆了多少天之后,系统就会送一些礼品给相应的用户.最常见的 莫过于游戏和商城这些.游戏就送游戏币之类的东西,商城就送一些礼券.正值国庆,应该也有不 ...

  8. Redis 实战 —— 11&period; 实现简单的社交网站

    简介 前面介绍了广告定向的实现,它是一个查询密集型 (query-intensive) 程序,所以每个发给它的请求都会引起大量计算.本文将实现一个简单的社交网站,则会尽可能地减少用户在查看页面时系统所 ...

  9. Spring Data Solr操作solr的简单案例

    Spring Data Solr简介 虽然支持任何编程语言的能力具有很大的市场价值,你可能感兴趣的问题是:我如何将Solr的应用集成到Spring中?可以,Spring Data Solr就是为了方便 ...

随机推荐

  1. jQuery 使用索引值容易出错的一个地方

    先看代码 $('input:eq(2)').attr('value', function(index, val){ console.log(index); //输出0 }); 问:当前元素的索引值,不 ...

  2. RealtekRTL8111内建网卡-黑苹果之路

    真是服了这神一样的黑苹果.好不容易配好显卡,登陆appstore却报“无法验证您的设备或电脑”,查了一圈,又说要配网卡为en0的,有说要在clover中配FIXLAN的,最准确的是网卡必须是内建(Bu ...

  3. 我与python3擦肩而过(二)—— csv文件头哪去啦?

    在看Python Data Visualization Cookbook 这本书(基于python2),开始时读取csv文件头的时候出现问题.查了资料,又是python3的问题,从这个链接找到答案. ...

  4. Some&lowbar;problem&lowbar;with&lowbar;octopress

    今天我总算是使用上了高大上的octopress了,不容易啊,现在我把之前的博客全部搬到了octopress上了,在github上办博客让我不用再担心流量和广告了!---爽啊 我使用octopress时 ...

  5. Swift 3&period;0 使用Core Data

    swift版本:3.0 Xcode版本:8.0 iOS版本:10.0 自iOS10 和swift3.0 之后,苹果的访问CoreData的方法发生了很大改变,简洁了许多,下面的内容是从0开始建立一个e ...

  6. java6内置JS引擎初接触

    本文系转载 原文地址:http://blog.csdn.net/sdyy321/article/details/6959199 由于要用到该技术,所以写了几个测试,直接上代码. 定义外部资源E:/Sc ...

  7. LR 常见问题总结

    问题1:Error: Two Way Communication Error:            Function two_way_comm_post_message/two_way_comm_p ...

  8. BZOJ1511&colon; &lbrack;POI2006&rsqb;OKR-Periods of Words

    1511: [POI2006]OKR-Periods of Words Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 174  Solved: 92[Su ...

  9. linux 输入输出重定向

    输入输出重定向 1,输入输出重定向,是针对过滤器的,不针对,编辑器和交互工具 2,>号只把正确的标准输出重定向,输出错误信息,可以用2> 3,新建或清空文件可以直接用>filenam ...

  10. sublime text 3 package Install 安装失败解决方法

    失败原因为官网地址被墙,导致channel_v3文件无法访问. 解决方法: 点击Preferences——>Package Settings——>Package Control——> ...