In Redis, the SORT
command allows us to sort lists, sets, and sorted sets.
We can have the sorted elements returned to the client, or we can store them in a separate key.
Syntax
SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern ...]] [ ASC | DESC] [ALPHA] [STORE destination]
The various options are explained in the following examples.
Example
Suppose we create a list:
LPUSH scores 10 8 3 7 5 12 7 0 1 9 2
Result:
(integer) 11
And let’s take a look at the list (without sorting it):
LRANGE scores 0 -1
Result:
1) "2" 2) "9" 3) "1" 4) "0" 5) "7" 6) "12" 7) "5" 8) "7" 9) "3" 10) "8" 11) "10"
Now let’s use the SORT
command to change the order:
SORT scores
Result:
1) "0" 2) "1" 3) "2" 4) "3" 5) "5" 6) "7" 7) "7" 8) "8" 9) "9" 10) "10" 11) "12"
The ASC
and DESC
Modifiers
By default, the SORT
command sorts the results in ascending order. So when using numbers, a list is sorted from small to large. We can explicitly enforce this with the ASC
modifier. We can use the DESC
modifier to sort from large to small.
Here’s the previous example again, but this time with the ASC
modifier:
SORT scores ASC
Result:
1) "0" 2) "1" 3) "2" 4) "3" 5) "5" 6) "7" 7) "7" 8) "8" 9) "9" 10) "10" 11) "12"
We get the same result as in the previous example.
Here it is with the DESC
modifier:
SORT scores DESC
Result:
1) "12" 2) "10" 3) "9" 4) "8" 5) "7" 6) "7" 7) "5" 8) "3" 9) "2" 10) "1" 11) "0"
The ALPHA
Modifier
We can use the ALPHA
modifier to sort string values lexicographically.
Suppose we create this list:
LPUSH pets "Tweet" "Fluffy" "Scratch" "Bark" "Fluffy" "Woof"
Result:
(integer) 6
We can look at its contents (unsorted):
LRANGE pets 0 -1
Result:
1) "Woof" 2) "Fluffy" 3) "Bark" 4) "Scratch" 5) "Fluffy" 6) "Tweet"
Now let’s use SORT
to sort the contents in ascending order:
SORT pets ALPHA
Result:
1) "Bark" 2) "Fluffy" 3) "Fluffy" 4) "Scratch" 5) "Tweet" 6) "Woof"
Or we can use the ASC
modifier to explicitly sort it in ascending order:
SORT pets ASC ALPHA
Result:
1) "Bark" 2) "Fluffy" 3) "Fluffy" 4) "Scratch" 5) "Tweet" 6) "Woof"
And here it is in descending order:
SORT pets DESC ALPHA
Result:
1) "Woof" 2) "Tweet" 3) "Scratch" 4) "Fluffy" 5) "Fluffy" 6) "Bark"
We can also apply the ALPHA
modifier on numbers to sort them alphabetically:
SORT scores ALPHA
Result:
1) "0" 2) "1" 3) "10" 4) "12" 5) "2" 6) "3" 7) "5" 8) "7" 9) "7" 10) "8" 11) "9"
The LIMIT
Modifier
We can use the LIMIT
modifier to limit how many elements are returned. This modifier takes an offset amount as well as the number of elements to return from that offset.
We can specify no offset by using 0
as the offset:
SORT pets LIMIT 0 3 ASC ALPHA
Result:
1) "Bark" 2) "Fluffy" 3) "Fluffy"
And here it is with an offset:
SORT pets LIMIT 2 3 ASC ALPHA
Result:
1) "Fluffy" 2) "Scratch" 3) "Tweet"
The BY
Option
We can use the BY
option to sort by external keys as weights to compare instead of comparing the actual elements in the list.
Suppose we create a list like this:
LPUSH uid 1 2 3 4 5
Result:
(integer) 5
And we set the following points_*
keys:
MSET points_1 500 points_2 200 points_3 300 points_4 400 points_5 100
Result:
OK
We can sort mylist
by the points_*
keys:
SORT uid BY points_* ASC
Result:
1) "5" 2) "2" 3) "3" 4) "4" 5) "1"
The order of the elements is reflective of the values in the points_*
keys.
Here it is when using DESC
for descending order:
SORT uid BY points_* DESC
Result:
1) "1" 2) "4" 3) "3" 4) "2" 5) "5"
Getting External Keys
The above technique can be handy when each list element represents a unique ID of a separate object. These objects can have their weights stored in external keys (in this case, the points_*
keys), which can be used for sorting them.
We can also use the GET
option of the SORT
command to retrieve the external keys.
Suppose we create the following objects:
MSET user_1 "Homer" user_2 "Bart" user_3 "Marge" user_4 "Maggie" user_5 "Milhouse"
Result:
OK
We can now build on the previous example by doing the following:
SORT uid BY points_* GET user_*
Result:
1) "Milhouse" 2) "Bart" 3) "Marge" 4) "Maggie" 5) "Homer"
Here it is in descending order:
SORT uid BY points_* GET user_* DESC
Result:
1) "Homer" 2) "Maggie" 3) "Marge" 4) "Bart" 5) "Milhouse"
We can also use another GET
with the #
pattern to get the other element:
SORT uid BY points_* GET user_* GET #
Result:
1) "Milhouse" 2) "5" 3) "Bart" 4) "2" 5) "Marge" 6) "3" 7) "Maggie" 8) "4" 9) "Homer" 10) "1"
For hash fields, we can use the following syntax for BY
and GET
:
SORT points BY weight_*->fieldname GET object_*->fieldname
Sorting by a Non-Existent Key
We can use the BY
option to sort by a key that doesn’t exist. When we do this, it skips the sorting altogether:
SORT points BY nonexistentkey
Result:
1) "3" 2) "2" 3) "4" 4) "1" 5) "5"
However, when we do this, the ASC
and DESC
modifiers still work:
SORT points BY nonexistentkey DESC
Result:
1) "5" 2) "1" 3) "4" 4) "2" 5) "3"
The STORE
Option
We can use the STORE
option to store the results of SORT
to a key.
Example:
SORT pets ALPHA STORE pets_sorted
Result:
(integer) 6
Now we can access the sorted results by accessing the new key without having to perform another SORT
operation:
LRANGE pets_sorted 0 -1
Result:
1) "Bark" 2) "Fluffy" 3) "Fluffy" 4) "Scratch" 5) "Tweet" 6) "Woof"