Redis SORT Command Explained

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"