我正在使用Redis排序集来存储我正在进行的项目的排名。我们没想到(!)我们想要如何处理关系。 Redis按字典顺序对具有相同分数的条目进行排序,但我们想要做的是对具有相同分数的所有条目赋予相同的等级,例如在
redis 127.0.0.1:6379> ZREVRANGE foo 0 -1 WITHSCORES
1) "first"
2) "3"
3) "second3"
4) "2"
5) "second2"
6) "2"
7) "second1"
8) "2"
9) "fifth"
10) "1"
我们要考虑second1
,second2
和second3
两者都有位置2,fifth
有位置5.因此在第三或第四位置没有进入。 ZREVRANK
在这里没用,那么获得我想要的数字的最佳方法是什么?
在我看来,一种方法是编写一个小的Lua脚本并使用EVAL
命令。由此产生的操作仍具有对数复杂性。
例如,假设我们对second2
的位置感兴趣。在剧本中,首先我们得到ZSCORE
的得分,获得2.然后我们使用ZRANGEBYSCORE
获得第一个带有该得分的条目,获得second3
。我们所追求的位置是ZREVRANK
加上1的second3
。
redis 127.0.0.1:6379> ZSCORE foo second2
"2"
redis 127.0.0.1:6379> ZREVRANGEBYSCORE foo 2 2 LIMIT 0 1
1) "second3"
redis 127.0.0.1:6379> ZREVRANK foo second3
(integer) 1
所以脚本可能是这样的
local score = redis.call('zscore', KEYS[1], ARGV[1])
if score then
local member = redis.call('zrevrangebyscore', KEYS[1], score, score, 'limit', 0, 1)
return redis.call('zrevrank', KEYS[1], member[1]) + 1
else return -1 end