Py学习  »  Redis

zrevrank在redis中的“公平”排名

Jan • 5 年前 • 915 次点击  

当我有一个带有分数的排序集时,即使多个项目具有相同的分数,我也希望拥有正确的排名。

例如,当有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脚本留给读者作为练习。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/30832
 
915 次点击  
文章 [ 2 ]  |  最新文章 5 年前
misterion
Reply   •   1 楼
misterion    5 年前

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

lex系列的已排序集命令允许您为具有相同值的键指定词典排序。

Kevin Christopher Henry
Reply   •   2 楼
Kevin Christopher Henry    5 年前

对于有分数的给定项目 x ,您可以确定其在o(log(n))时间中的排名 ZCOUNT (X +inf .

具体如何利用它取决于实现的细节。