Geocoding and coordinates are a common use case in modern applications. These computations can be very heavy in terms of lookups so it is often desired to cache. Thus, Redis provides us with the geo data type to make using coordinates easy. In this article, we will learn how to use the Geo Data Type in Redis with 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
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.
We can add items to a geo set using the following. The example below will create a Geo Set called Sicilty that is a sorted set. We will then add Palermo then add Catania with their respective longitude and latitude.
# Geo Add r.geoadd("Sicily", 13.361389, 38.115556, "Palermo") r.geoadd("Sicily", 15.087269, 37.502669, "Catania")
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) # Geo Add r.geoadd("Sicily", 13.361389, 38.115556, "Palermo") r.geoadd("Sicily", 15.087269, 37.502669, "Catania")
Once we have a geo set, we can start to do calulcations on it. For example, we can get the distance between two members using the following.
# Geo Dist const result = r.geodist("Sicily", "Palermo", "Catania") print(result) # 166274.1516
We can also get all items within a radius using the
# Geo Radius - key for geo hash, long, latitude, radius, unit const result = r.georadius("Sicily", 15, 27, 200, "km") print(result) # 2
If we would like to get the specific hash for our geo sets, we can use
# Geo Hash const result = r.geohash("Sicily", "Palermo", "Catania") print(result) # [ 'sqc8b49rny0', 'sqdtr74hyu0' ]
geopos class will return the position of members in our geo hash.
# Geo Position const result = r.geopos("Sicily", "Palermo", "Catania", "Random") print(result) # [ # [ '13.36138933897018433', '38.11555639549629859' ], # [ '15.08726745843887329', '37.50266842333162032' ], # null # ]
To get the distance between two members, we can use the
geodist command. We have the option to specificy the units.
# Geo Distance const result = r.geodist("Sicily", "Palermo", "Catania") print(result) # 166274.1516 const result2 = r.geodist("Sicily", "Palermo", "Catania", "km") print(result2) # 166.2742
geosearch command provides an api to allow us to search the geo members of our set.
# Geo Search const result = r.geosearch("Sicily", "FROMLONLAT", 15, 37, "BYRADIUS", 200, "km", "ASC") print(result) # [ 'Catania', 'Palermo' ]