【问题标题】:ZREVRANK 'fair' ranking in REDISZREVRANK 在 REDIS 中的“公平”排名
【发布时间】: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


【解决方案1】:

对于得分为x 的给定项目,您可以使用ZCOUNT (X +inf 确定其在O(log(N)) 时间内的排名。

你如何使用它取决于你的实现细节。

【讨论】:

    【解决方案2】:

    ZREVRANGEBYLEX 在这种情况下可以使用。在这种情况下,时间复杂度为 O(log(N)+M),其中 N 是排序集中的元素数,M 是返回的元素数。语法请查看ZRANGEBYLEX

    Lex 系列的 sorted set 命令允许您为具有相同值的键指定字典顺序。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-10
      • 2018-12-25
      • 2012-12-04
      相关资源
      最近更新 更多