Redis, Part 2: Lists
Welcome to Part 2 in my series of posts about Redis, a key-value database and open source project created by Salvatore Sanfilippo. In Part 1, we discussed some basic Redis commands: getting and setting values, testing for key existence, and incrementing and decrementing values. Standard stuff in the world of key-value databases. This time, we’ll explore something more interesting: lists.
(If you haven’t read Part 1 yet, please do so before continuing.)
A list is an ordered collection of values. Think of it like an array in your favorite programming language. You can insert values at the beginning (left) and end (right) of the list, retrieve single and ranges of elements, and delete elements.
To follow along with these examples, start the Redis server and then connect with telnet, just like we did in part 1.
Let’s create a new list:
% LPUSH vowels 1 % a +OK
Inserting an element is called pushing. Because the key
vowels doesn’t exist yet, a new list is created with a single value,
a. Let’s add two more values to the list, this time at the end:
% RPUSH vowels 1 % e +OK % RPUSH vowels 1 % i +OK
We’ve pushed three values into our list; let’s make sure Redis agrees.
% LLEN vowels :3
Now that we have some values in the list, how do we get them back out?
Redis has a few commands for retrieving list elements; which command to use depends on how many elements we wish to retrieve.
We can get a single value back with the
LINDEX command. Lists in Redis are zero-based, so the first element of a list has index 0, the second has index 1, and so on. So far our list has values
i. Let’s get each by its index.
% LINDEX vowels 0 $1 a % LINDEX vowels 1 $1 e % LINDEX vowels 2 $1 i
If we try to get the value at an index that doesn’t exists, Redis returns a null value.
% LINDEX vowels 3 $-1
Suppose we want the last (right-most) value in the list, but we don’t know how long it is. Using a negative index, we can get elements starting at the end of the list:
% LINDEX vowels -1 $1 i % LINDEX vowels -2 $1 e
We can retrieve more than one value using the
LRANGE command, which takes three arguments: the key, the start index, and the end index. To get the first two elements in the list:
% LRANGE vowels 0 1 *2 $1 a $1 e
(The first line reads
*2, which means two elements are being returned.)
LRANGE accepts negative indices, just like
LINDEX. Let’s get all the elements in the list:
% LRANGE vowels 0 -1 *3 $1 a $1 e $1 i
By making both indices negative, we can get the last two values out of the list:
% LRANGE vowels -2 -1 *2 $1 e $1 i
Suppose we executed a few more commands and now
vowels looks like this:
y, j, u, x, o, j, a, e, i, x, j, j. Let’s clean it up by removing the extra elements.
First, let’s delete the
y at index 0. One way is to use the
LPOP removes and returns the first element of the list:
% LPOP vowels $1 y
We can also
RPOP, which does the same thing to the last element of the list.
Another option is to trim the list to a smaller version of itself. We can do this with the
LTRIM works exactly like
LRANGE except instead of returning the range Redis overwrites the key with it:
% LTRIM vowels 1 -1 +OK
This command sets
vowels to be the range starting at index 1 and ending at the last element.
vowels now contains these elements:
u, x, o, j, a, e, i, x, j, j.
Let’s get rid of those
js using the
LREM takes three arguments: a key to operate on, the number of matching elements to remove, and the value to remove1.
Let’s remove the first
% LREM vowels 1 1 % j :1
1 tells Redis to start searching at the first element and to remove one instance of
j. (The second
1 is the size in bytes of the value for which to search.) Redis responds with
:1, the number of elements removed.
Let’s remove two more
js, this time from the end of the list:
% LREM vowels -2 1 % j :2
-2 tells Redis to remove two elements and, because of the negative sign, to search starting at the end of the list. Two elements have been removed, so Redis says
Now our list is
u, x, o, a, e, i, x. Let’s remove all of the
xs in one go:
% LREM vowels 0 1 % x :2
0 as the second argument we’re telling Redis to remove all
We have a complete list of vowels–
u, o, a, e, i–but they’re in the wrong order. Let’s get a sorted list of vowels:
% SORT vowels ALPHA *5 $1 a $1 e $1 i $1 o $1 u
SORT is a powerful command with many options and we’ll cover it later in greater detail. For now, here are a couple more things you can do with
Sort in the opposite direction:
% SORT vowels ALPHA DESC *5 $1 u $1 o $1 i $1 e $1 a
Limit the returned list to 3 elements, starting at index 1:
% SORT vowels LIMIT 1 3 ALPHA *3 $1 e $1 i $1 o
So far, we’ve only had a taste of why Redis is so exciting. Next time we’ll look at sets and things will really pick up.
Redis can’t remove an element by index. There will always be a delay between when a command is sent and executed–during that delay, the list could be modified by another client and the index would then reference the wrong element.