This is part 7 of my Node/Redis series. You can read Part 1, Dancing around strings in Node.js and Redis, Part 2, Store Javascript objects in Redis with Node.js the right way, Part 3 Using the Redis multi object in Node.js for fun and profit, Part 4 Keeping track of account subscriptions with Redis and Node.js, Part 5 Managing modularity and Redis connections in Node.js, Part 6 Redis, Express and Streaming with Node.js and Classic Literature and Part 8 Redis, set, node.
The sort command is arguably the most complex command in Redis. You can simply sort a set or you can sort by external keys in hashes. Very different. The syntax of the command is dense but it makes sense after you get the hang of it. In Node, you’ve probably grown used to how node_redis can seamlessly handle saving objects with hmset or getting objects with hgetall. You can be in for a rude awaking when you expect something like that from the results of Sort with external keys.
Let’s say you have a set storing a bunch of username keys and a corresponding hash for each member of the set. It looks something like this:
Note: I generated a bunch of fake data for this article using faker.js. It works great — I suggest it if you’re playing about or you want to do some profiling with realistic data.
Now, lets say you want to sort by the users name (stored in the hash’s name field). We’ll build a straight forward script like this:
This sorts by the user’s name then gets the user’s key (#), name (*->name), color (*->color) and state (*->state). The output of this will just be an array of values in the order that you’ve specified in the sort command’s get arguments. It’ll look like this:
If you ask me, that is pretty useless. I’ve spent many hours writing various functions to deserialize the results of a sort. Invariably, at some later point, I’ll throw another field in the sort command and mess up my results. It’s fragile and brittle. Let’s make it easier, more flexible and generalized.
Essentially, what we need to do is parse the sort command’s arguments and find the field names specified using get. Then we will chopthe redis results array into chunks that are the length of the output object. Finally we’ll reassemble (aka zipObject) the values of each chunk with the field names.
So, the reassembleSort acts as a shim between the regular node_redis sort function and your data. It passes the data back to the callback function the normal way and it will pass along any errors just the same as well. You’ll get something more useful:
Now, you can add and remove hash external fields from your sort command without worrying that you may break your deserialization function. While this does have some overhead, we’re using lodash to do most of the array manipulation and it is quite quick.