阅读量:0
1 实现点赞功能显示哪些用户点赞过并安装时间顺序排序
使用sort_set 进行存储,把博客id作为key,用户id作为value,时间戳作为score
但存储成功之后还是没有成功按照时间顺序排名,因为sql语句,比如最后in(5,1)、
我们要按照用户id5和3和1来显示,但sql会默认显示135,要修改sql语句order byfiled(id,5,1,3)按照自己定义的数据
@Override public Result like(Long id) { String key = RedisConstants.BLOG_LIKED_KEY + id; Blog blog = getById(id); //获取登录用户 Long userId = UserHolder.getUser().getId(); //判断当前登录用户是否点赞 Double isMember = stringRedisTemplate.opsForZSet().score(key,userId.toString()); //如果未点赞可以点 if(isMember == null){ //+1 boolean isUpdate = update().set("liked", blog.getLiked() + 1).eq("id", id).update(); if(BooleanUtil.isTrue(isUpdate)){ //zadd key value score stringRedisTemplate.opsForZSet().add(key,userId.toString(),System.currentTimeMillis()); } }else { stringRedisTemplate.opsForZSet().remove(key,userId.toString()); //如果已经点赞则取消 boolean isUpdate = update().set("liked", blog.getLiked() - 1).eq("id", id).update(); //-1 //从redis中去除 } return null; }
@Override public Result queryBlogLikes(Long id) { //查询前五点赞的人 Set<String> top5 = stringRedisTemplate.opsForZSet().range(RedisConstants.BLOG_LIKED_KEY + id, 0, 4); if(top5 == null || top5.isEmpty()){ return Result.ok(Collections.emptyList()); } //解析出用户id List<Long> ids = top5.stream().map(Long::valueOf).collect(Collectors.toList()); List<UserDTO> userDTOS = new ArrayList<>(); //根据id查出用户 ids.forEach(userId -> { User user = userService.getById(userId); UserDTO userDTO = new UserDTO(); BeanUtils.copyProperties(user,userDTO); userDTOS.add(userDTO); }); return Result.ok(userDTOS); }
2 使用set集合记录共同关注
每个人关注时,往以自己id为key的set集合里面添加被关注的人的id,查看另一个用户的共同关注时,可以使用set集合的intersect查看交集id,再通过id流操作得到被关注的User对象
@Override public Result followCommons(Long id) { if (UserHolder.getUser() != null) { Long userId = UserHolder.getUser().getId(); String key = "follows:" + userId; String key2 = "follows" + id; Set<String> intersect = stringRedisTemplate.opsForSet().intersect(key,key2); if(intersect == null || intersect.isEmpty()){ return Result.ok(Collections.emptyList()); } //解析id集 //使用流操作 List<Long> ids = intersect.stream().map(Long::valueOf).collect(Collectors.toList()); List<UserDTO> collects = userService.listByIds(ids).stream().map(user -> { return BeanUtil.copyProperties(user, UserDTO.class); }).collect(Collectors.toList()); return Result.ok(collects); } return Result.fail("共同关注发生问题"); } }
3 使用sortedset记录滚动分页查询
修改代码,在有用户保存发送新的博客时,将查询数据库中他的所有粉丝,并以粉丝为key,博客id为value,当前时间戳为为score进行保存,在粉丝点击自己的关注时,将按照时间戳的从大到小进行分页查询,记录上一次查询到什么数据,将其时间戳的下一个作为下一次的起始,再加上偏移量,zset默认按照score从小到大进行排序
Set<ZSetOperations.TypedTuple<String>> typedTuples = stringRedisTemplate.opsForZSet().reverseRangeByScoreWithScores(RedisConstants.FEED_KEY + userId, 0, max, offset, 2);
查找按照分数反向排序0 - max范围内的2个数据,offset就是从第一个下面offset个开始,比如为5,5,4,2,1
按照当前查找是得到5,5(第二个5)
然后max 变成第二个5
然后后面再从中查找找到的是第一个5,所以要加上偏移量1,也就是从4开始
@Override public Result saveBlog(Blog blog) { UserDTO user = UserHolder.getUser(); blog.setUserId(user.getId()); // 保存探店博文 blogService.save(blog); //查询笔记作者的粉丝 List<Follow> follows = followService.lambdaQuery().eq(Follow::getFollowUserId, user.getId()).list(); //推送笔记id给所有粉丝 for(Follow follow : follows){ Long userId = follow.getUserId(); String key = RedisConstants.FEED_KEY + userId; stringRedisTemplate.opsForZSet().add(key,blog.getId().toString(),System.currentTimeMillis()); } // 返回id return Result.ok(blog.getId()); } @Override public Result queryBlogOfFollow(Long max, Integer offset) { Long userId = UserHolder.getUser().getId(); //查询收件箱 Set<ZSetOperations.TypedTuple<String>> typedTuples = stringRedisTemplate.opsForZSet().reverseRangeByScoreWithScores(RedisConstants.FEED_KEY + userId, 0, max, offset, 2); if(typedTuples == null || typedTuples.isEmpty()){ return Result.ok(); } //解析数据 blogId,时间戳,offset List<Long> ids = new ArrayList<>(typedTuples.size()); Long minTime = 0L; int os = 1; for(ZSetOperations.TypedTuple<String> tuple : typedTuples){ //获取id String idStr = tuple.getValue(); if (idStr != null) { ids.add(Long.valueOf(idStr)); } //获取分数时间戳 long time = Objects.requireNonNull(tuple.getScore()).longValue(); if(time == minTime){ os++; }else{ minTime = time; os = 1; } } String idStr = StrUtil.join(",",ids); //根据id查询blog List<Blog> blogs = query().in("id", ids).last("ORDER BY FIELD(id," + idStr + ")").list(); for (Blog blog : blogs){ User user = userService.getById(userId); blog.setName(user.getNickName()); blog.setIcon(user.getIcon()); isLiked(blog); } ScrollResult r = new ScrollResult(); r.setList(blogs); r.setOffset(os); r.setMinTime(minTime); return Result.ok(r); } }