Redis zrevrangebyscore,除字典序以外的排序 [英] Redis zrevrangebyscore, sorting other than lexicographical order

查看:37
本文介绍了Redis zrevrangebyscore,除字典序以外的排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 redis 中使用排序集实现了排行榜.我希望分数相同的用户按时间顺序排列,即首先出现的用户排名更高.目前 redis 支持字典序.有没有办法覆盖它.手机号码被用作排序集中的成员.

I have implemented a leader board using sorted sets in redis. I want users with same scores to be ordered in chronological order, i.e., user who came first should be ranked higher. Currently redis supports lexicographical order. Is there a way to override that. Mobile numbers are being used as members in sorted set.

我想到的一个解决方案是在手机号码前附加时间戳并维护一个哈希来映射手机号码和时间戳.

One solution that I thought of is appending timestamp in front of mobile numbers and maintaining a hash to map mobile number and timestamp.

$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}")

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

That way I can get rank for a given user at any instance by adding a prefix from hash.

现在这不是我想要的.这将返回与我想要的相反.早到的用户将排在晚到的用户下方(两者得分相同).

Now this is not exactly what I want. This will return opposite of what I want. User who comes early will be placed below user who comes later(both with same score).

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

如果我使用 zrevrangebyscore,user2 将高于 user1.

if I use zrevrangebyscore, user2 will be placed higher than user1.

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

However, there's a way to get the desired rank:

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

现在我有一个正确排序的列表users_with_same_score.查看索引我可以计算用户的排名.

Now I have the list users_with_same_score with correct ordering. Looking at index I can calculate rank of the user.

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

To get leader board. I can get members in intervals of 50 and order them through ruby code. But it doesn't seems to be a good way.

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

I want to know if there's a better approach to do it. Or any improvements that can be made in solution I purposed.

预先感谢您的帮助.

附言分数是 50 的倍数

推荐答案

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

The score in a sorted set supports double precision floating point numbers, so possibly a better solution would be to store the redis score as highscore.timestamp

例如(伪代码)

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

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

This would mean that multiple players who achieved the same high score will also be sorted based on the time they achieved that high score as per the following

对于玩家 1...

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

对于玩家 2...

redis.zadd('myleaderboard', '100.1362345399', "Babbage")

查看此问题了解更多详情:redis 排行榜的独特评分

See this question for more detail: Unique scoring for redis leaderboard

这篇关于Redis zrevrangebyscore,除字典序以外的排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆