Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort sets by number of elements in Redis

Tags:

redis

I have a Redis database with a number of sets, all identified by a common key pattern, let's say "myset:".

Is there a way, from the command line client, to sort all my sets by number of elements they contain and return that information? The SORT command only takes single keys, as far as I understand.

I know I can do it quite easily with a programming language, but I prefer to be able to do it without having to install any driver, programming environment and so on on the server.

Thanks for your help.

like image 935
fpighi Avatar asked Feb 19 '23 05:02

fpighi


2 Answers

No, there is no easy trick to do this.

Redis is a store, not really a database management system. It supports no query language. If you need some data to be retrieved, then you have to anticipate the access paths and design the data structure accordingly.

For instance in your example, you could maintain a zset while adding/removing items from the sets you are interested in. In this zset, the value will be the key of the set, and the score the cardinality of the set.

Retrieving the content of the zset by rank will give you the sets sorted by cardinality.

If you did not plan for this access path and still need the data, you will have no other choice than using a programming language. If you cannot install any Redis driver, then you could work from a Redis dump file (to be generated by the BGSAVE command), download this file to another box, and use the following package from Sripathi Krishnan to parse it and calculate the statistics you require.

https://github.com/sripathikrishnan/redis-rdb-tools

like image 105
Didier Spezia Avatar answered Feb 24 '23 15:02

Didier Spezia


Caveat: The approach in this answer is not intended as a general solution -- remember that use of the keys command is discouraged in a production setting.

That said, here's a solution which will output the set name followed by it's length (cardinality), sorted by cardinality.

# Capture the names of the keys (sets)
KEYS=$(redis-cli keys 'myset:*')

# Paste each line from the key names with the output of `redis-cli scard key`
# and sort on the second key - the size - in reverse

paste <(echo "$KEYS") <(echo "$KEYS" | sed 's/^/scard /' | redis-cli) | sort -k2 -r -n

Note the use of the paste command above. I count on redis-cli to send me the results in order, which I'm pretty sure it will do. So paste will take one name from the $KEYS and one value from the redis output and output them on a single line.

like image 21
Linus Thiel Avatar answered Feb 24 '23 17:02

Linus Thiel