How can I get all of the sets in redis?
I know the KEYS command, but that only returns the keys (I'm guessing all of the keys with type String), and apparently sets aren't considered keys.
KEYS command return results no matter what data type are your keys, since it searches key names. At the lowest level of abstraction each data type in redis is key/value based where value can be represented as one of several (advanced) data structures (string, hash, list, set, sorted set). You can see that KEYS command also work for sets in it's examples.
Is there a command for getting all of the sets in the database? What about other data types (hash, list, sorted set)?
As far as I know there is no dedicated command for this functionality and KEYS command is applied on entire data set of your database. However there is a TYPE command which can determine data type of specified key.
The answer was correct for its time, however this is supported from redis 2.8.0 - Check out SCAN
As of version 6.0, you can use SCAN 0 TYPE set
. See https://redis.io/commands/scan#the-type-option
For versions prior to 6.0, you can use a Lua script to filter server-side, saving Round Trip Time (RTT) of doing TYPE
calls back from the client.
EVAL "local result = redis.call('SCAN', ARGV[1], 'MATCH', ARGV[2]) local filtered = {} for _,key in ipairs(result[2]) do if redis.call('TYPE', key).ok == ARGV[3] then table.insert(filtered, key) end end result[2] = filtered return result" 0 0 * set
The parameters to the script are 0(numkeys) cursor matchPattern type
. E.g. 0 0 * set
Here a friendly view of the Lua script:
local result = redis.call('SCAN', ARGV[1], 'MATCH', ARGV[2])
local filtered = {}
for _,key in ipairs(result[2]) do
if redis.call('TYPE', key).ok == ARGV[3] then
table.insert(filtered, key)
end
end
result[2] = filtered
return result
The returned value is the same as with SCAN
, just with the list of keys filtered by type.
As with SCAN
, you need to call multiple times until the cursor returned is zero.
This approach is much better than using KEYS
, as it won't block the server for a long time.
Next is the same script but with COUNT option, to do less or more work per call. The count should be greater than zero.
EVAL "local result = redis.call('SCAN', ARGV[1], 'MATCH', ARGV[2], 'COUNT', ARGV[3]) local filtered = {} for _,key in ipairs(result[2]) do if redis.call('TYPE', key).ok == ARGV[4] then table.insert(filtered, key) end end result[2] = filtered return result" 0 0 * 100 set
The parameters to the script are 0(numkeys) cursor matchPattern count type
. E.g. 0 0 * 100 set