随机查询若干数据,并根据全部数据的点击量排序的核心代码
需求:随机展示六条帖子,并把这几条帖子的热度按照总的点击量进行分类,在全部点击量排前100的帖子为高热,100到1000名为热,1000到5000为火…
也就是说,我需要随机查询六条数据,并得到这六条数据的点击量在全部数据的点击量中的排序位置。
1、点击量存储
首先将帖子具体数据存放在数据库中,但是帖子每次被点击,在redis中将帖子的点击量+1,核心实现如下:
存储点击量: 当你的数据被点击时,你可以使用ZSetOperations的incrementScore()方法增加该数据在有序集合中的分数。这个分数可以代表点击量。
// 获取ZSetOperations对象来操作有序集合
ZSetOperations<String, String> ops = redisTemplate.opsForZSet();
// 假设 "data123" 被点击了
double score = ops.incrementScore("my_set", "data123", 1);
如果你是一开始就要存储一些初始点击量,你可以直接在有序集合中添加数据和对应的点击量分数。
// 假设 "data456" 初始点击量为 10
ops.add("my_set", "data456", 10);
这样,当你执行上述查询代码时,这个有序集合的分数就可以代表点击量,rank()方法就会返回基于点击量的排名。
要注意的是,使用有序集合(Sorted Set)的好处是,它可以根据你的点击量(分数)对数据进行排序,这样就可以非常高效地获取点击量的排名。同时,在这个结构中,每个成员都是唯一的,但分数可以重复。这非常适合用来存储和查询点击量排名这样的场景。
如果在执行double score = ops.incrementScore(“my_set”, “data123”, 1);之前,Redis中没有这条数据(“data123”),那么这条命令会在有序集合my_set中添加这条数据,并将其分数设置为1。
因此,无论你的数据是否已经在Redis中存在,你都可以使用incrementScore()方法来增加它的点击量分数,并且不会影响已有的数据结构和数据。这个方法是非常灵活和高效的,特别适用于记录像点击量这样的可以累加的数据。
2、随机查询6条数据,并返回他们在全部数据中的排序
我是主体数据在mysql中存储,点击量数据在redis记录。
如果是在数据库中存储的数据主体,随机获取6条记录的sql如下:
<select id="xxxx" resultMap="BaseResultMap">select * from 表名 where xxx=#{xxx,jdbcType=VARCHAR} and isdelete='0' order by RAND() LIMIT 6</select>
如果是在redis中存储的数据主体,随机获取6条记录的逻辑如下:
List<String> allRecords = listOperations.range("allRecords", 0, -1); // 获取所有记录 Random random = new Random(); List<String> randomSixRecords = random.ints(0, allRecords.size()) // 随机选择6个记录的索引 .distinct() .limit(6) .mapToObj(index -> allRecords.get(index)) .toList();
获取点击量的排序:
// 获取这6条数据在全体数据中的点击量排名 for (String d : data) { Double rank = ops.rank("my_set", d); System.out.println("Data: " + d + ", Rank: " + rank); } //获取到了排序位置后,可以自己根据自己需要进行逻辑处理了。