'Redis Command To Sort Keys

The Redis command keys * will return a list of all keys and scan 0 is a more recent way to do something similar, but with less blocking. Do any commands exist that can sort the keys found, such as alphabetically, numerically, by creation timestamp, etc.?

Example of standard and fancy command sought:

standard keys post:* command:

post:2150
post:2400
post:1001
post:1006

fancy command to sort the keys alphabetically:

post:1001
post:1006
post:2150
post:2400


Solution 1:[1]

Redis returns keys, using KEYS (don't use it in production!) or SCAN, unordered. There is no "fancy" API to return them sorted but you can do it in the client application.

Solution 2:[2]

You can always use your unix commands which works perfectly

redis-cli --scan --pattern yourpattern* | sort

Solution 3:[3]

For completeness sake:

You technically can do this within the context of Redis, using the EVAL command.

This would get all keys according to the post:* pattern, then sort the keys, and use them to MGET all the items.

EVAL "local keys = redis.call('KEYS','post:*');
      if (table.getn(keys) == 0) then return {} end;
      table.sort(keys);
      return redis.call('MGET',unpack(keys));"

This approach can increase performance, but manipulating Redis using LUA scripts might feel inelegant.

There are also issues with the KEYS command, and some safety considerations with EVAL of course.

I would say that the "Proper Redis Way" to solve this, would be to design a "composite data structure" around the use case:

// a scoreless sorted set can be used as an index
SET post:1500 <value>
ZADD posts_index 0 post:1500

// Whenever you need a sorted (range) of items, you first check the index 
ZRANGE posts_index - + BYLEX 
ZRANGE posts_index [posts:1000 (posts:2000 BYLEX 

The sorted set posts_index is just a set of all the keys in the post "namespace". Of course, if you set TTLs or remove items from cache, you will need to manage this for the posts_index set as well.

The result of ZRANGE is sorted, and can be used to GET/MGET items

The advantage of this over client-side sorting is performance: It's pre-sorted, and you can split it into ranges, use cursors to only hold a few items in memory at a time, etc.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Itamar Haber
Solution 2 Guido Dizioli
Solution 3 okdewit