日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

使用redis的zset实现排行榜

發(fā)布時間:2025/3/20 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用redis的zset实现排行榜 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1.使用場景

現(xiàn)在公司有個項目,類似于今日頭條,需要實現(xiàn)對應(yīng)分類閱讀排行榜的功能。

每一篇文章所屬于一個分類,當(dāng)用戶閱讀該文章時,閱讀次數(shù)+1,排行榜實時變化。

2.redis的ZSet數(shù)據(jù)結(jié)構(gòu)

zset為有序集合。就是在set的基礎(chǔ)上,添加了一個score值。zset的每一個成員都有一個分?jǐn)?shù)與之對應(yīng),并且分?jǐn)?shù)可以重復(fù)。score就相當(dāng)于權(quán)重,可以根據(jù)score值進(jìn)行排序展示。

項目中使用了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):通過索引區(qū)間返回有序集合成指定區(qū)間內(nèi)的成員,其中有序集成員按分?jǐn)?shù)值遞增(從小到大)順序排列

  • Set<TypedTuple<V>> rangeWithScores(K key, long start, long end):通過索引區(qū)間返回有序集合成指定區(qū)間內(nèi)的成員對象,其中有序集成員按分?jǐn)?shù)值遞增(從小到大)順序排列

  • Set<V> rangeByScore(K key, double min, double max):通過分?jǐn)?shù)返回有序集合指定區(qū)間內(nèi)的成員,其中有序集成員按分?jǐn)?shù)值遞增(從小到大)順序排列

  • Set<V> reverseRange(K key, long start, long end):通過索引區(qū)間返回有序集合成指定區(qū)間內(nèi)的成員,其中有序集成員按分?jǐn)?shù)值遞減(從大到小)順序排列

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

3.代碼實例

(1)項目中的緩存常量類

CacheConstant.java

? ?/*** 分類研報購買次數(shù)*/public static final String REPORT_CATEGORY_BUY_COUNT = "report_report_category_buy_count:";

(2)CacheService.java

? ?@Autowiredprivate RedisTemplate<String, Object> template; ?/*** 增加研報分類閱讀次數(shù)(查看文章詳情接口時調(diào)用)** @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的參數(shù)代表查詢該key下的所有valuereturn template.opsForZSet().reverseRange(CacheConstant.REPORT_CATEGORY_READ_COUNT, 0, -1);} else {return new HashSet<>();}} ? ?/*** 獲取研報分類閱讀排行榜具體分類次數(shù)*/public Double getReportCategoryBuyCount(Object o) {return template.opsForZSet().score(CacheConstant.REPORT_CATEGORY_BUY_COUNT, o);}
  • 這里我們將分類在數(shù)據(jù)庫中的主鍵id存進(jìn)去,以便按順序查出來之后去數(shù)據(jù)庫中查詢對應(yīng)的分類名。

  • score值就是該文章的閱讀次數(shù),可以直接調(diào)用接口獲取

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<>();//一次性查詢出所有一級分類,然后和分類排行榜的對應(yīng)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;}

?

總結(jié)

以上是生活随笔為你收集整理的使用redis的zset实现排行榜的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。