Redis:获取排序集的所有分数

时间:2013-01-23 18:43:40

标签: database nosql redis

我需要为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 个答案:

答案 0 :(得分: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"]

答案 1 :(得分: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个项目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的新手,所以也许有更优雅的方法来实现同样的目标。

答案 2 :(得分:1)

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

  

ZREVRANGE键开始停止[WITHSCORES]返回a中的一系列成员   排序集,按索引,分数从高到低排序

答案 3 :(得分:0)

对于ruby,以下命令将执行

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

来源Ruby Docs