Redis:获取有序集合中所有可用的分数

8

我需要获取redis排序集中的所有可用分数。

redis>  ZADD myzset 10 "one"

(integer) 1

redis>  ZADD myzset 20 "two"

(integer) 1

redis>  ZADD myzset 30 "three"

(integer) 1

现在我想检索myzset的所有分数,即10、20、30。
4个回答

8

编辑: 由于您之前的问题并未明确指出数值大小的问题,因此我进行了一些额外的研究。

根据当前的文档,似乎没有办法只获取已排序集合中的分数。

要获取分数,您需要同时将它们添加到另一个集合中,并在需要时从该集合中获取。

不过,您首先应该尝试将问题映射到不同的数据结构中。我无法从您的问题中看出为什么需要获取分数,但可能有其他更适用于Redis的解决方法。

--

我不确定是否有任何方法可以在不获取键的情况下获取所有分数,但ZRANGE至少可以获取您要查找的信息;

redis>  ZADD myzset 10 "one"
(integer) 1

redis>  ZADD myzset 20 "two"
(integer) 1

redis>  ZADD myzset 30 "three"
(integer) 1

redis> ZRANGE myzset 0 -1 WITHSCORES
["one","10","two","20","three","30"]

我知道,但是问题在于我的情况中数值非常大,仅跟踪分数是有问题的。 - biztiger
@biztiger 已更新。显然不是完美的解决方案,但如果您确实需要该功能,这是可行的。 - Joachim Isaksson

5

解决这个问题的一种方法是使用服务器端Lua脚本。

考虑以下脚本:

local res = {}
local result = {}
local tmp = redis.call( 'zrange', KEYS[1], 0, -1, 'withscores' )
for i=1,#tmp,2 do
   res[tmp[i+1]]=true
end
for k,_ in pairs(res) do
   table.insert(result,k)
end
return result

您可以通过使用EVAL命令来执行它。
它使用zrange命令来提取zset(带有分数的)的内容,然后构建一个集合(用Lua中的表表示),以去除冗余的分数,并最终构建回复表。因此,zset的值从未通过网络发送。
如果zset中的项目数量非常高,则此脚本存在缺陷,因为它会将整个zset复制到Lua对象中(因此它会占用内存)。但是,很容易将其更改为按增量迭代zset(每20个项目一次)。例如:
local res = {}
local result = {}
local n = redis.call( 'zcard', KEYS[1] )
local i=0
while i<n do
   local tmp = redis.call( 'zrange', KEYS[1], i, i+20, 'withscores' )
   for j=1,#tmp,2 do
      res[tmp[j+1]]=true
      i = i + 1
   end
end
for k,_ in pairs(res) do
   table.insert(result,k)
end
return result

请注意,我对Lua完全是个新手,因此可能有更优雅的方法来实现相同的事情。


1

您需要传递可选参数WITHSCORES。请参阅此处的文档here:

ZREVRANGE key start stop [WITHSCORES] 按索引返回有序集合中得分从高到低排列的成员范围


0

当涉及到Ruby时,以下命令将起作用

redis.zrange("zset", 0, -1, :with_scores => true)
# => [["a", 32.0], ["b", 64.0]]

源代码 Ruby文档


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接