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.