小编典典

Redis zrevrangebyscore,按字典顺序排序

redis

我已经在Redis中使用排序集实现了排行榜。我希望具有相同分数的用户按时间顺序排序,即,第一名的用户应排名更高。当前,redis支持词典顺序。有没有一种方法可以覆盖它。手机号码被用作排序集中的成员。

我想到的一种解决方案是在移动电话号码之前添加时间戳,并维护散列以映射移动电话号码和时间戳。

$redis.hset('mobile_time', '1234567890', "#{Time.now.strftime('%y%m%d%H%M%S')}")
pref = $redis.hget('mobile_time, '1234567890'')
$redis.zadd('myleaderboard', "1234567890:#{pref}")

这样,在任何情况下,我都可以通过从哈希添加前缀来获得给定用户的排名。

现在这不是我想要的。这将与我想要的相反。早到的用户将被置于晚到的用户下方(两者得分相同)。

Key for user1 = 201210121953**23**01234567890    score: 400
key for user2 = 201210121253**26**09313123523    score: 400 (3 seconds later)

如果我使用zrevrangebyscore,则将user2放置在高于user1的位置。

但是,有一种方法可以获取所需的排名:

users_with_higher_score_count = $redis.zcount("mysset", "(400", "+inf")
users_with_same_score = $redis.zrangebyscore("mysset", "400", "400")

现在,我具有正确顺序的列表 users_with_same_score 。查看索引,我可以计算出用户的排名。

获得排行榜。我可以以50个间隔获取成员,并通过ruby代码对其进行排序。但这似乎不是一个好方法。

我想知道是否有更好的方法可以做到这一点。或可以在我打算的解决方案中进行的任何改进。

在此先感谢您的帮助。

PS 分数是50的倍数


阅读 670

收藏
2020-06-20

共1个答案

小编典典

排序集中的分数支持双精度浮点数,因此可能更好的解决方案是将redis分数存储为highscore.timestamp

例如(伪代码)

highscore = 100
timestamp = now()
redis.zadd('myleaderboard', highscore + '.' + timestamp, playerId)

这意味着获得相同高分的多个玩家也将根据其获得高分的时间进行排序,如下所示:

对于玩家1 …

redis.zadd('myleaderboard', '100.1362345366', "Charles")

对于玩家2 …

redis.zadd('myleaderboard', '100.1362345399', "Babbage")
2020-06-20