一、特性说明
- ZSet采用了一种跳跃表的实现。
- ZSet数据是有序的
二、常用命令
(一)ZADD
命令格式: zadd key score member [[score member]...]
功能:往有序集合key中存入带分值元素
demo说明:
(二)ZREM
命令格式: zrem key member [member..]
功能:从有序集合key中删除元素
demo说明:
(三)ZSCORE
命令格式: zscore key member
功能:返回有序集合key中元素member的分值
demo说明:
(四)ZINCRBY
命令格式: zincrby key increment member
功能:为有序集合key中的元素member的分值加上increment
demo说明:
(五)ZCARD
命令格式: zcard key
功能:返回元素集合key中元素个数
demo说明:
(六)ZRANGE
命令格式: zrange key start stop [WITHSCORES]
功能:正序获取有序集合key从start下标到stop下标的元素
demo说明:
(七)ZREVRANGE
命令格式: zrevrange key start stop [member]
功能:倒序获取有序集合key从start下标到stop下标的元素
demo说明:
(八)ZUNIONSTORE
命令格式: zunionstore destkey numkeys member [member]
功能:并集运算
demo说明:
(九)ZINTERSTORE
命令格式: zinterstore destkey numkeys key [key]
功能:交集运算
demo说明:
三、应用场景
(一)微博热点排行版
类似需要有个数值排序的都可以考虑该方案
1、需求
实现每分钟当天的热点资讯排行榜
实现查看七天热点资讯排行榜
2、设计
- 每条的资讯键设计为 {date}:hotnews:{id}
- 用户点击一次则累计一次
- 查看排行榜则取当日集合按分值排序
- 查看七天排行榜则取七日做一个并集处理,然后再按分值排序取出
3、开发
查看资讯接口
@ApiOperation("查看资讯")
@PostMapping(value = "/viewNews")
public void viewNews(Long newsId) throws Exception{
LocalDate localDate = LocalDate.now();
String todayKey = localDate.plusDays(0).toString().replace("-", "") + "hotnews";
redisTemplate.opsForZSet().incrementScore(todayKey,newsId,1);
}
获取当日热点排行榜接口
@ApiOperation("获取当日热点排行榜")
@PostMapping(value = "/getHotNewsList")
public void getHotNewsList(Long newsId) throws Exception{
LocalDate localDate = LocalDate.now();
String todayKey = localDate.plusDays(0).toString().replace("-", "") + "hotnews";
Set set = redisTemplate.opsForZSet().reverseRange(todayKey, 0, 9);
//得到资讯id再查询资讯信息
System.out.println(set);
}
用个定时任务隔几分钟计算一次七日排行
//用个定时任务隔几分钟计算一次
public void countLastSevenHotNews(){
LocalDate localDate = LocalDate.now();
//今日
String todayKey = localDate.plusDays(0).toString().replace("-", "") + "hotnews";
//七日排行结果数据key
String destKey =localDate.plusDays(-6).toString().replace("-", "") +"-"+ todayKey +"hotnews";
//过去6天的key
List<String> list = new LinkedList<>();
for (int i = -1; i >= -6; i--) {
String key = localDate.plusDays(i).toString().replace("-", "")+"hotnews";
list.add(key);
}
//将今日和过去六天的key集合取并集 把结果放入七天结果集合
Long aLong = redisTemplate.opsForZSet().unionAndStore(localDate.plusDays(-1).toString().replace("-", "") + "hotnews", list, destKey);
}
获取最近七天热点排行榜接口
@ApiOperation("获取最近七天热点排行榜")
@PostMapping(value = "/getLastSevenHotNewsList")
public void getLastSevenHotNewsList() throws Exception{
LocalDate localDate = LocalDate.now();
//七日排行结果数据key
String destKey =localDate.plusDays(-6).toString().replace("-", "") +"-"+ todayKey +"hotnews";
//取出七天排行榜
Set set = redisTemplate.opsForZSet().reverseRange(destKey, 0, 9);
System.out.println(set);
}