Sorted sets are a powerful data set used in redis. If you are familiar with binary search, you know the importance of having a presorted set to access items in log(n). This data type is often used in analytics and leaderboards. In this article, we will learn how to work with sorted sets in Redis and Python.
For setting up Redis, I would recommend using a service for you in prod. Azure for example, has a great redis service that scales easily. However, you will want to learn redis and eventually how to scale it yourself. This will help with debugging cloud services or eventually, saving money and not using them.
We will start our intro to redis via using docker compose. Create a docker-compose.yml
file and add the following.
version: "3.2"
services:
redis:
image: "redis:alpine"
command: redis-server
ports:
- "6379:6379"
volumes:
- $PWD/redis-data:/var/lib/redis
- $PWD/redis.conf:/usr/local/etc/redis/redis.conf
environment:
- REDIS_REPLICATION_MODE=master
Ensure you have docker installed and run
docker-compose up
In python, the main used redis module is called redis-py
and can be installed using the follows.
pip install redis
Let's open up a new file, index.py
and go through many of
the common commands you will used with lists in redis.
Let's open up a new file, index.py
and go through many of
the common commands you will used with lists in redis.
We can create a Sorted Set and add a value to the set using the following. The example below is similar to creating a unique list so:
movieRatings = [
{
"key": "star-wars",
"score": 4,
},
{
"key": "marvel",
"score": 5,
}
]
We can add items to a sorted set by using the zadd
method. We pass in the name of the set, the score, then the key we want to add the score too.
# Sorted Set Add
r.zadd("movie-ratings", 4, "star-wars")
r.zadd("movie-ratings", 5, "marvel")
We can get the member of a sorted set using the zrange
function. We pass the set name, the start index, then the end index.
# Sorted Set Range
r.zrange("movie-ratings", 1, 3)
print(result) # [ 'marvel' ]
For each of the examples below, I will use the following template to run all the commands. Here is my full index file. We will just replace the commands each time.
import redis
r = redis.Redis(host='localhost', port=6379, db=0)
# Sorted Set Add
r.zadd("movie-ratings", 4, "star-wars")
r.zadd("movie-ratings", 5, "marvel")
If we want to get the size of our set, we can use zcard
.
def sortedSetSize():
# Sorted Set Count
r.zcard("movie-ratings")
print(result) # 2
We can count the number of items between a min and max value using the zcount
method.
def sortedSetCount():
# Sorted Set Count
r.zcount("movie-ratings", 4, 5)
print(result) # 2
const result2 = await redis.zcount("movie-ratings", 1, 3)
print(result2) # 0
Sorted set range will return a list of items within an index. We can also use 0, -1 to select all item in the set.
def sortedSetRange():
# Sorted Set Range
r.zrange("movie-ratings", 1, 3)
print(result) # [ 'marvel' ]
const result2 = await redis.zrange("movie-ratings", 0, -1)
print(result2) # [ 'star-wars', 'marvel' ]
To get the different or elements in one set and not another, we can use the zdiff
function.
def sortedSetDiff():
# Sorted Set Diff
await redis.zadd("movie-ratings-user2", 3, "marvel")
const numberOfSets = 2
r.zdiff(numberOfSets, "movie-ratings", "movie-ratings-user2")
print(result) # [ 'star-wars' ]
Similar to the above, we can use the zinter
method to see the items shared amongst two sets.
def sortedSetInter():
# Sorted Set Intersection
await redis.zadd("movie-ratings-user2", 3, "marvel")
const numberOfSets = 2
r.zinter(numberOfSets, "movie-ratings", "movie-ratings-user2")
print(result) # [ 'marvel' ]
If we want to increment a a score, we can use zincrby
. Below we increment the rating of new-movie
by 2.
def sortedSetIncrementBy():
# Sorted Set Increment By
await redis.zadd("movie-ratings", 4, "new-movie")
await redis.zincrby("movie-ratings", 2, "new-movie")
If we have a list of keys, and we want to get their scores, we can use the zmscore
.
def sortedSetMultipleScore():
# Sorted Set Multiple Score
r.zmscore("movie-ratings", "star-wars", "marvel")
print(result) # [ '4', '5' ]
To get the ranking of a specific item, think position on a leader board, we can use the zrank
method.
def sortedSetRank():
# Sorted Set Rank
r.zrank("movie-ratings", "star-wars")
print(result) # 1
const result2 = await redis.zrank("movie-ratings", "marvel")
print(result2) # 2