前言:
redis中的set可以实现共同好友,点赞,关注等功能,其zset结构可以实现排行榜的功能。还有另外4种数据结构(BitMap,HyperLoglog等等),也是利用他们的特点优势,实现了其他场景。
点赞排行榜实现
一个事物的好坏,取决于客户对其的评价,所以在很多平台上面我们经常会看见评分,点赞等。最后通过统计,罗列出一个排行榜。排行榜的实现其实有很多的方法。在这里对最早点赞的人(top5)进行显示,前面我们使用的是redis中的set对用户,文章id进行存储,并没有排序功能,在想其实redis中有一种数据结构是可以在满足数据唯一的基础上实现排序的,也就是我们所说的zset。
在文章详情处,将点赞人数显示出来,比如最早(按时间)点赞的top5,形成点赞排行榜。
接口设计
代码实现
采用set的数据结构进行数据存储的,现在我们修改一下原有的数据结构,将数据结构转换成zset进行存储。
/**
* 修改点赞功能,利用Redis的set集合判断是否点赞过,未点赞过则点赞数+1,已点赞则点赞-1;
*/
@Override
public Result likeBlog(Long id) {
// 1.获取登录用户
Long userId = UserHolder.getUser().getId();
// 2.判断用户是否点过赞
Double score = stringRedisTemplate.opsForZSet().score(RedisConstants.BLOG_LIKED_KEY + id, userId.toString());
if (score != null){
// 点赞 ; 取消用户点赞,
boolean update = update().setSql("liked = liked - 1").eq("id", id).update();
if (!update) {
return Result.fail(SystemConstants.BLOG_CANCEL_LIKE_FAIL);
}
stringRedisTemplate.opsForZSet().remove(RedisConstants.BLOG_LIKED_KEY+id,userId.toString());
}else {
boolean update = update().setSql("liked = liked + 1").eq("id", id).update();
if (!update) {
return Result.fail(SystemConstants.BLOG_LIKE_FAIL);
}
stringRedisTemplate.opsForZSet().add(RedisConstants.BLOG_LIKED_KEY+id,userId.toString(),System.currentTimeMillis());
}
return Result.ok();
}
接口的编写
添加/likes/{id}的请求路径及方法
获取zset中排名top5的用户id
@Override
public Result queryBlogLikes(Long id) {
// 根据文章id,查询redis中排名前五的用户信息
Set range = stringRedisTemplate.opsForZSet().range(RedisConstants.BLOG_LIKED_KEY + id, 0, 4);
if (range == null || range.isEmpty()) {
return Result.ok(Collections.emptyList());
}
// 获取用户id
List ids = range.stream().map(Long::valueOf).toList();
List topUserList = new ArrayList<>();
List userDTOList = ids.stream().map(u -> {
User user = userService.getById(u);
UserDTO userDTO = BeanUtil.copyProperties(user, UserDTO.class);
topUserList.add(userDTO);
return userDTO;
}).collect(Collectors.toList());
return Result.ok(userDTOList);
}
总结
上述是基于redis简单实现排行榜的功能,项目需求中有时候会考虑实现排行榜的功能。上述分析可以做个参考。