Redis有序集合和解决绑定问题

我正在使用 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"

我们希望认为second1second2 second3 的位置都为第 2 位,fifth 的位置为第 5 位。 因此,第三或第四位置没有条目。 ZREVRANK 在这里没有用,那么得到我要找的数字的最佳方法是什么?

点赞
用户991296
用户991296

我认为一种方法是编写一个小 Lua 脚本并使用 EVAL 命令。生成的操作仍然具有对数复杂度。

例如,假设我们对 second2 的位置感兴趣。在脚本中,首先我们使用 ZSCORE 获取其分数为 2。然后我们使用 ZRANGEBYSCORE 获取具有该分数的第一项,得到 second3。我们要找的位置是 second3ZREVRANK 加 1。

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
2013-02-18 19:57:39