Redis Best Practices

Geospatial

Redis has several commands related to geospatial indexing (GEO commands) but unlike other commands these commands lack their own data type. These commands actually piggy back on the sorted set datatype. This is achieved by encoding the latitude and longitude into the score of the sorted set using the geohash algorithm.

Adding items to a geospatial index is easy. As an example, let’s assume you are tracking a group of cars as they travel down the road – we’ll call this set of cars simply “cars”. We’ll say your specific car can be identified as the member “my-car” (we use the term member because a geo index is just a form of a set). To add car to the set, we can run the command:

> GEOADD cars -115.17087 36.12306 my-car 

The first argument is the set we’re adding to, the second is the longitude, third is the latitude and the fourth is the member name.

To update the location of the car, you’ll just need to run the command again with new coordinates. This works because the geo index is just a set – repeated items are not allowed.

> GEOADD cars -115.17172 36.12196 my-car

Let’s add a second car to the “cars” set – this time it’s driven by Robin:

> GEOADD cars -115.171971 36.120609 robins-car

Looking at the coordinates, you can tell these two cars are quite close, but how close? You can determine this by running the GEODIST command.

> GEODIST cars my-car robins-car
"90.7082"

This means the two vehicles are about 90 meters apart. You can also specify other units:

> GEODIST cars my-car robins-car ft
"297.5990"

This has pulled the same distance in feet. You can also use Miles (mi) or Kilometers (km).

Now, let’s see what items are in a radius from a certain point:

> GEORADIUS cars -115.17258 36.11996 100 m
1) "my-car"
2) "robins-car"

This returns all the members with 100 meters of the point given. You can also return members within a radius of another member in the set:

> GEORADIUSBYMEMBER cars robins-car 100 m
1) "robins-car"
2) "my-car"

We can also include the distance by adding in the optional argument WITHDIST  – this works for GEORADIUS or GEORADIUSBYMEMBER:

> GEORADIUSBYMEMBER cars robins-car 100 m WITHDIST
1) 1) "robins-car"
   2) "0.0000"
2) 1) "my-car"
   2) "90.7082"

Another optional argument for both GEORADIUS and GEORADIUSBYMEMBER is WITHCOORD which returns the coordinates for each member. WITHDIST and WITHCOORD can be used together or separately:

> GEORADIUSBYMEMBER cars robins-car 100 m WITHDIST WITHCOORD
1) 1) "robins-car"
   2) "0.0000"
   3) 1) "-115.17197102308273315"
      2) "36.12060917648089031"
2) 1) "my-car"
   2) "90.7082"
   3) 1) "-115.17258256673812866"
      2) "36.11996028786411017"

Since geospatial indexes are just an alternate way of manipulating Sorted Sets, some operations can be achieved just by using the sorted set commands. If we want to remove “my-car” from the “cars” set, we’d need to use the sorted set command ZREM:

> ZREM cars my-car

Redis provides a rich set of geospatial manipulation tools and only the basics were covered in this pattern. You can read more about the full set of commands on redis.io.