Redis构建文章聚合信息分类网站
本系列教程内容提要
Java工程师之Redis实战系列教程教程是一个学习教程,是关于Java工程师的Redis知识的实战系列教程,本系列教程均以解决特定问题为目标,使用Redis快速解决在实际生产中的相关问题,为了更方便的与大家一起探讨与学习,每个章节均提供尽可能详细的示例源码及注释,所有示例源码均可在javacourse-redis-in-action找到相关帮助!
你思考过这个问题吗?
如果你想过自己开发一个论坛网站,或者文章网站?最起码想过开发自己的博客网站吧?那么你是否考虑过这个问题--“当你数据库查询你的记录时,你考虑过这些记录应当以什么样的方式展现在网页?按发布时间?按浏览次数?
- 按发布时间(嗯,应当时没问题的...)
- 按浏览次数(嗯,如果给定一个时间范围也是没问题的...)
你是否浏览过stackoverflow,如下图所示,你是否考虑过这些记录时按照什么展现的呢?唔...经过你的长久思考后,你想“应该不是最新,也不是浏览最多,应该时经过一系列的机制后算出来的....”

我们通过什么机制进行排序呢?
既然你能想到一定是经过一系列的运算过程的出来的排序过程,那么我们可否设计一个符合我们自己网站的 "运算过程" 呢? 我们规定:
- 文章的发布时间+A支持票乘以常量E-B反对票乘以常量E
- 文章7天后不再支持投支持票/反对票
设计Redis表结构
| 表名 | 结构 |
|---|---|
| 文章 | HASH |
| 投票人 | SET |
| 群组 | SET |
| 文章评分排行 | ZSET |
| 文章最新排行 | ZSET |
| 群组最新文章 | ZSET |
| 群组评分排行 | ZSET |

核心源码
查询文章 (查询功能做的最多的就是拼装数据,但是在查询某个群组的文章的时候,就是涉及到了Redis的交集运算)
/**
* 获得所有文章列表文章列表
*
* @param page 页数
* @param order 排序
* @param model 模型
* @return
*/
@GetMapping(value = "/getArticleList")
public String getArticle(@RequestParam(required = false, defaultValue = "1") Integer page, @RequestParam(required = false, defaultValue = "score") String order, Model model) {
/*获取文章列表*/
List<Article> articleArrayList = getArticles(jedis, page, order + ":");
/*拼装分页信息*/
model.addAttribute("articleArrayList", articleArrayList);
model.addAttribute("order", order);
model.addAttribute("page", page);
return "index";
}
/**
* 获取分组文章列表
*
* @return
*/
@GetMapping(value = "/getGroupArticleList")
public String getGroupArticle(@RequestParam(required = false, defaultValue = "1") Integer page,
@RequestParam(required = false, defaultValue = "score") String order,
@RequestParam(required = true) String group, Model model) {
List<Article> groupArticles = getGroupArticles(jedis, group, page, order + ":");
/*拼装分页信息*/
model.addAttribute("groupArticles", groupArticles);
model.addAttribute("group", group);
model.addAttribute("order", order);
model.addAttribute("page", page);
return "group";
}
发布文章 (发布文章需要注意的是根据文章的所属群组,将其添加至相关群组)
/**
* 发布文章
*
* @param article
* @param model
* @return
*/
@PostMapping(value = "/addArticle")
public String addArticle(Article article, Model model) {
/*模拟用户*/
User user = getUser();
/*从Redis获取文章的自增ID*/
String id = String.valueOf(jedis.incr("article:"));
/*将文章的发帖人本人添加至投票列表*/
String voted = "voted:" + id;
jedis.sadd(voted, user.getUserId().toString());
jedis.expire(voted, ONE_WEEK_IN_SECONDS);
/*将文章添加至文章列表*/
long now = System.currentTimeMillis() / 1000;
String articleId = "article:" + id;
HashMap<String, String> articleData = new HashMap<>();
articleData.put("title", article.getTitle());
articleData.put("link", article.getLink());
articleData.put("user", user.getUserId().toString());
articleData.put("time", String.valueOf(now));
articleData.put("votes", "1");
articleData.put("group", article.getGroup());
articleData.put("opposeVotes", "0");
jedis.hmset(articleId, articleData);
/*将文章添加至分值列表*/
jedis.zadd("score:", now + VOTE_SCORE, articleId);
/*将文章添加至发布时间列表*/
jedis.zadd("time:", now, articleId);
/*将文章加入其所属分组*/
addGroup(jedis, articleId, new String[]{article.getGroup()});
/*设置模型数据*/
model.addAttribute("page", 1);
model.addAttribute("order", "score");
return "redirect:/article/getArticleList";
}
投票 (根据我们前面的规定,7天后不再提供对该文章的投票功能,所以需要在进行投票之前注意文章的发布时间)
/**
* 投票
*
* @param articleId
* @param model
* @return
*/
@GetMapping(value = "/articleVote")
public String articleVote(Integer articleId, int tag, RedirectAttributes model) {
/*模拟用户*/
User user = getUser();
String result = article_vote(jedis, user, articleId, tag);
/*设置模型数据*/
model.addFlashAttribute("result", result);
model.addFlashAttribute("page", 1);
model.addFlashAttribute("order", "score");
return "redirect:/article/getArticleList";
}
运行效果图
各位友友可以下载本章的示例源码,运行访问 http://localhost:8080/article/getArticleList


本章源码提供完整的运行环境源码GitHub下载
Redis构建文章聚合信息分类网站的更多相关文章
- 使用Redis构建文章投票网站
涉及到的key: 1. article_time, 记录文章的发布时间,zset结构 2. article_score, 记录文章的得分, zset结构 得分 = 发布时间 + 投票用户数 X 432 ...
- 使用redis构建文章投票系统
首先,我得说明这篇博客基本上就是<<redis in action>>第一章内容的读书笔记. 需求 首先,说明一下,我们的需求 用户可以发表文章,发表时,自己就默认的给自己的文 ...
- redis 实例2 构建文章投票网站后端
redis 实例2 构建文章投票网站后端 1.限制条件 一.如果网站获得200张支持票,那么这篇文章被设置成有趣的文章 二.如果网站发布的文章中有一定数量被认定为有趣的文章,那么这些文章需要被设置 ...
- redis实战笔记(6)-第6章 使用 Redis构建应用程序组件
本章主要内容 1.构建两个前缀匹配自 动补全程序 2.通过构建分布式锁来提高性能 3.通过开发计数信号量来控制并发 4.构建两个不同用途的任务队列 5.通过消息拉取系统来实现延迟消息传递 6.学习 ...
- redis实战笔记(2)-第2章 使用 Redis构建Web应用
第2章 使用 Redis构建Web应用 本章主要内容 1.登录cookie 2.购物车cookie 3.缓存生成的网页 4.缓存数据库行 5.分析网页访问记录 本章的所有内容都是围绕着发现并解 ...
- 《Redis官方文档》用Redis构建分布式锁
用Redis构建分布式锁 在不同进程需要互斥地访问共享资源时,分布式锁是一种非常有用的技术手段. 有很多三方库和文章描述如何用Redis实现一个分布式锁管理器,但是这些库实现的方式差别很大,而且很多简 ...
- Redis系列文章-数据结构篇
Redis系列文章 前言: 工作原因,在学习mybatis知识后,2个月没有补充新的知识了,最近拿起书本开始学习.打算写下这个Redis系列的文章. 目录结构如下: Redis内置数据结构 Redis ...
- 七、Abp vNext 基础篇丨文章聚合功能下
介绍 不好意思这篇文章应该早点更新的,这几天在忙CICD的东西没顾得上,等后面整好了CICD我也发2篇文章讲讲,咱们进入正题,这一章来补全剩下的 2个接口和将文章聚合进行完善. 开工 上一章大部分业务 ...
- nginx+lua+redis构建高并发应用(转)
nginx+lua+redis构建高并发应用 ngx_lua将lua嵌入到nginx,让nginx执行lua脚本,高并发,非阻塞的处理各种请求. url请求nginx服务器,然后lua查询redis, ...
随机推荐
- 20 款免费的 JavaScript 游戏引擎
使用 HTML5,CSS3 和 Javascript 可以帮助面向对象开发者开发拥有各种特性的游戏,比如:3D 动画效果,Canvas,数学,颜色,声音,WebGL 等等.最明显的优势在于使用 HTM ...
- thinkphp 查询指定分类下的文章
$list = $Dao->query("SELECT xp_wztj.bt,xp_wztj.time,xp_wztj.gjz,xp_wztj.wz,xp_wzfl.name FROM ...
- MyEclipse实现xml的自动提示
每次出现不能自动提示,蛮烦的.虽然不是一个很难的问题,但是有时候就是记得这个很简单的几步,所以记录下来以备用. 现在mybatis主要是3版本,即此时根据版本3来写的,别的都一样. 1,下载dtd文件 ...
- sqlserver 字符串split
select value from TF_NJVALUES('3C457A2D-188B-4D99-A822-2968054E1FB8,3C457A2D-188B-4D99-A822-2968054E ...
- link with editor
在左侧explore上,有个双向的箭头,点一下,就会把路径和当前文件自动对应
- AssetBundle中Unload()方法的作用
AssetBundle.Unload(false)的作用: 官网的解释是这样的: When unloadAllLoadedObjects is false, compressed file data ...
- python2.0_s12_day19_前端结合后端展示客户咨询纪录
接下来就是将后台视图与前端页面结合起来了完成后台系统了.实现前端展示用户列表1.先在base.html代码中把模版中Dashboard下面的内容清空,如下: 具体删除哪些html代码,自己找吧.2.我 ...
- ch6-定制数据对象(打包代码和数据)
为了看出数据属于哪个选手,教练向各个选手的数据文件中添加了标识数据:选手全名,出生日期,计时数据. 例如:sarah文件的数据更新为: Sarah Sweeney,2002-6-17,2:58,2.5 ...
- Python 入门(四)List和Tuple类型
创建list Python内置的一种数据类型是列表:list.list是一种有序的集合,可以随时添加和删除其中的元素. 比如,列出班里所有同学的名字,就可以用一个list表示: >>> ...
- AssetBundle 在Android机子上进行读取 .
http://game.ceeger.com/Manual/StreamingAssets.html 我看到官方文档中说明:Note that bundles are not fully compat ...