欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

使用redis的zset实现排行榜

发布时间:2025/3/20 45 豆豆
生活随笔 收集整理的这篇文章主要介绍了 使用redis的zset实现排行榜 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

1.使用场景

现在公司有个项目,类似于今日头条,需要实现对应分类阅读排行榜的功能。

每一篇文章所属于一个分类,当用户阅读该文章时,阅读次数+1,排行榜实时变化。

2.redis的ZSet数据结构

zset为有序集合。就是在set的基础上,添加了一个score值。zset的每一个成员都有一个分数与之对应,并且分数可以重复。score就相当于权重,可以根据score值进行排序展示。

项目中使用了SpringBoot整合的redisTemplate

常用方法如下:

  • Boolean add(K key, V value, double score):新增一个有序集合,存在的话为false,不存在的话为true

  • Long add(K key, Set<TypedTuple<V>> tuples):新增一个有序集合

  • Long remove(K key, Object... values):从有序集合中移除一个或者多个元素

  • Double incrementScore(K key, V value, double delta):增加元素的score值,并返回增加后的值

  • Set<V> range(K key, long start, long end):通过索引区间返回有序集合成指定区间内的成员,其中有序集成员按分数值递增(从小到大)顺序排列

  • Set<TypedTuple<V>> rangeWithScores(K key, long start, long end):通过索引区间返回有序集合成指定区间内的成员对象,其中有序集成员按分数值递增(从小到大)顺序排列

  • Set<V> rangeByScore(K key, double min, double max):通过分数返回有序集合指定区间内的成员,其中有序集成员按分数值递增(从小到大)顺序排列

  • Set<V> reverseRange(K key, long start, long end):通过索引区间返回有序集合成指定区间内的成员,其中有序集成员按分数值递减(从大到小)顺序排列

  • Double score(K key, Object o):获取指定成员的score值

3.代码实例

(1)项目中的缓存常量类

CacheConstant.java

   /*** 分类研报购买次数*/public static final String REPORT_CATEGORY_BUY_COUNT = "report_report_category_buy_count:";

(2)CacheService.java

   @Autowiredprivate RedisTemplate<String, Object> template; ​/*** 增加研报分类阅读次数(查看文章详情接口时调用)** @param categoryId*/public void incrReportCategoryReadCount(Long categoryId) {template.opsForZSet().incrementScore(CacheConstant.REPORT_CATEGORY_READ_COUNT, categoryId, 1);} ​/*** 获取研报分类阅读排行榜*/public Set<Object> getReportCategoryReadCountRank() {if (template.hasKey(CacheConstant.REPORT_CATEGORY_READ_COUNT)) {//0,-1的参数代表查询该key下的所有valuereturn template.opsForZSet().reverseRange(CacheConstant.REPORT_CATEGORY_READ_COUNT, 0, -1);} else {return new HashSet<>();}} ​ ​/*** 获取研报分类阅读排行榜具体分类次数*/public Double getReportCategoryBuyCount(Object o) {return template.opsForZSet().score(CacheConstant.REPORT_CATEGORY_BUY_COUNT, o);}
  • 这里我们将分类在数据库中的主键id存进去,以便按顺序查出来之后去数据库中查询对应的分类名。

  • score值就是该文章的阅读次数,可以直接调用接口获取

4.Rank.java

   public static class Rank implements Serializable {private Long id;private String name;private Integer times;}

5.StatisticService.java

   @Autowiredprivate CacheService cacheService; ​public StatisticsPlatformResponse platform() {        //查询一级分类下的研报阅读排行List<Rank> readRank = new ArrayList<>();//一次性查询出所有一级分类,然后和分类排行榜的对应id去匹配List<ReportCategory> oneCategoryList = reportCategoryService.findAllOneCategory(); ​Set<Object> readCountRank = cacheService.getReportCategoryReadCountRank();if (readCountRank != null) {for (Object o : readCountRank) {Rank singReadRank = getRank(oneCategoryList, (Number) o);singReadRank.setTimes(cacheService.getReportCategoryReadCount(o).intValue());readRank.add(singReadRank);}}return readRank;} ​private Rank getRank(List<ReportCategory> oneCategoryList, Number o) {Rank rank = new Rank();rank.setId(o.longValue());rank.setName(getCategoryName(o.longValue(), oneCategoryList));return rank;}/*** 获取分类名** @param categoryId* @param list* @return*/private String getCategoryName(Long categoryId, List<ReportCategory> list) {for (ReportCategory category : list) {if (category.getId().equals(categoryId)) {return category.getName();}}return null;}

 

总结

以上是生活随笔为你收集整理的使用redis的zset实现排行榜的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。