Redis:分类集中的SCORES总和

ma1*_*w28 7 sum sortedset redis

在Redis排序集中获取SCORES总和的最佳方法是什么?

ant*_*rez 16

我认为唯一的选择是迭代排序集并计算客户端总和.


Ita*_*ber 11

可用,因为Redis v2.6是在Redis服务器上执行Lua脚本的最强大功能.这使得将分类集的分数总结为微不足道的挑战:

local sum=0
local z=redis.call('ZRANGE', KEYS[1], 0, -1, 'WITHSCORES')

for i=2, #z, 2 do 
    sum=sum+z[i]
end

return sum
Run Code Online (Sandbox Code Playgroud)

运行时示例:

~$ redis-cli zadd z 1 a 2 b 3 c 4 d 5 e
(integer) 5
~$ redis-cli eval "local sum=0 local z=redis.call('ZRANGE', KEYS[1], 0, -1, 'WITHSCORES') for i=2, #z, 2 do sum=sum+z[i] end return sum" 1 z
(integer) 15
Run Code Online (Sandbox Code Playgroud)

  • 一个重要的注意事项是Redis服务器端lua脚本阻止了一切,在大多数情况下这可能是一个破解者.资料来源:http://stackoverflow.com/a/30896608/2440 (4认同)

mkg*_*der 5

如果集合很小,并且您不需要出色的性能,我只会迭代 (zrange/zrangebyscore) 并对客户端的值求和。

另一方面,如果您谈论的是数千至数百万件物品,您始终可以为每个用户保留一个包含运行总数的参考集,并在发送礼物时增加/减少它们。

所以当你做你的ZINCR 123:gifts 1 "3|345",你可以做一个单独的 ZINCR 命令,它可能是这样的:

ZINCR received-gifts 1 <user_id>
Run Code Online (Sandbox Code Playgroud)

然后,要获取给定用户收到的礼物数量,您只需要运行 ZSCORE:

ZSCORE received-gifts <user_id>
Run Code Online (Sandbox Code Playgroud)

  • 显然这个答案已经很老了,但是,为什么要对“单独的命令”使用 ZSET 呢?从您的回答中我不清楚,据我所知,仅使用 INCR/GET 也能正常工作(并使用更少的内存)。 (2认同)