Redis: get all grades for a sorted set
One way to solve this problem is to use server-side Lua scripts.
Consider the following script:
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 You can execute it using the EVAL command.
It uses the zrange command to retrieve the contents of the zset (with grades), then it creates a set (represented by a table in Lua) to remove excess points and finally creates a response table. Thus, zset values ββare never sent over the network.
This script has a drawback if the number of elements in zset is really large, as it copies the entire zset in the Lua object (therefore, it takes memory). However, it is easy to change it to iterate over zset gradually (20 elements by 20 elements). For instance:
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 Note that I'm new to Lua, so there are more elegant ways to achieve the same.
EDIT . Since your problem with the size of the values ββwas not obvious before, I did some additional research.
According to current documentation, it is not possible to get only grades from a sorted set.
What you need to do to get only grades is to add them to a separate set at the same time and get them from there when necessary.
What you should probably do first is try to map your problem differently with data structures. I canβt say from your question why you need to get points, but there may be other ways to structure the problem that Redis displays better.
-
I'm not sure that you can get all the points without getting the keys, but ZRANGE will at least get the information you are looking for;
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"]