【发布时间】:2019-01-23 17:19:40
【问题描述】:
当我有一个带有分数的排序集时,即使多个项目具有相同的分数,我也希望获得正确的排名。
例如,当有 5 个项目的分数为:1、2、2、2、3,我希望这三个中心项目具有相同的排名 (1),而最高分数的排名为 0 (使用 ZREVRANGE),最低的获得 4 级。
我发现可以查询具有相同分数的键的数量有点有效 O(log(N)),但看起来如果我想获得我想要的分数,我必须使用zscan,即 O(N)。
编辑:根据接受的解决方案添加完整示例
我们的数据集是一个带有分数的排序集。例如:a 得分为 1,b、c 和 d 得分为 2,e 得分为 3:
127.0.0.1:6379> zadd aset 1 a
(integer) 1
127.0.0.1:6379> zadd aset 2 b
(integer) 1
127.0.0.1:6379> zadd aset 2 c
(integer) 1
127.0.0.1:6379> zadd aset 2 d
(integer) 1
127.0.0.1:6379> zadd aset 3 e
(integer) 1
ZREVRANK 适用于具有唯一分数的项目:
127.0.0.1:6379> zrevrank aset a
(integer) 4
127.0.0.1:6379> zrevrank aset e
(integer) 0
但是对于那些分数相同的项目它会失败:
127.0.0.1:6379> zrevrank aset b
(integer) 3
127.0.0.1:6379> zrevrank aset c
(integer) 2
127.0.0.1:6379> zrevrank aset d
(integer) 1
要解决这个问题,首先使用ZSCORE 获取分数:
127.0.0.1:6379> zscore aset c
"2"
当然,其他项目的分数相同:
127.0.0.1:6379> zscore aset b
"2"
127.0.0.1:6379> zscore aset d
"2"
要获得他们的排名,只需将ZCOUNT 与分数一起使用:
127.0.0.1:6379> zcount aset (2 +inf
(integer) 1
这也适用于那些具有唯一分数的项目:
127.0.0.1:6379> zcount aset (1 +inf
(integer) 4
127.0.0.1:6379> zcount aset (3 +inf
(integer) 0
将其编写为原子 lua 脚本留作读者练习。
【问题讨论】:
-
@Kevin Christopher Hery 的回答很棒。还要检查类似的question
-
天哪,你的答案是我拼命寻找沙中的钻石!你让我免于被解雇,伙计!
标签: redis