GEO Usage of Redis Advanced Data Structure

Keywords: Redis Database SQL

demand

How to implement a "accessory person" or a nearby "store" function?

requirement analysis

It can be done based on the database, given a coordinate, with this coordinate as the radius r, j uses sql to select the elements of the approximate circle for display.

select id from positions where x > x0-r and x < x0+r and y < y0+r and y> y0-r

But if the amount of access is very large, the database can't do anything. Fortunately, Redis provides a GEO module, which can be used directly.

GeoHash algorithm is the most common geographic location distance sorting algorithm in the industry. Redis also uses GeoHash algorithm. GeoHash algorithm maps two-dimensional longitude and latitude data to one-dimensional integers, so that all elements will be mounted on a line, and the distance between two-dimensional coordinates near to the point after one-dimensional mapping will be very close.

The GeoHash algorithm will continue to encode the integer base32 once (0-9,a-z removes the four letters a,i,l,o) into a string. In Redis, longitude and latitude are encoded using 52-bit integers and put into zset, where the value of Zset is the key of the element and score is GeoHash's 52-bit integer value. Zset's score is a floating-point number, but it can be stored losslessly for 52-bit integer values.

When using Redis for Geo queries, we need to keep in mind that its internal structure is actually just a zset(skiplist). The other elements near the coordinates can be obtained by the score sort of zset (the actual situation is more complicated, but this understanding is enough), and the original coordinates of the elements can be obtained by reducing the score to the coordinate value.

Redis GEO module use

> GEOADD key longitude latitude member //Adds a given spatial element (latitude, longitude, name) to the specified key. 
> GEOPOS key member //Return the longitude and latitude of member
> GEODIST key member1 member2 [unit] //Distance between two elements
> GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [ASC|DESC] [COUNT count] //With the given latitude and longitude as the center, the return key contains all the location elements whose distance from the center does not exceed the given maximum distance.
> GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [ASC|DESC] [COUNT count] //This command, like the GEORADIUS command, can find elements within a specified range, but the central point of GEORADIUSBYMEMBER is determined by the given location element.
> GEOHASH key member //Returns an array. Each item in an array is a geohash
//The examples are as follows.
redis> GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania"
(integer) 2

redis> GEODIST Sicily Palermo Catania
"166274.15156960039"

redis> GEORADIUS Sicily 15 37 100 km
1) "Catania"

redis> GEORADIUS Sicily 15 37 200 km
1) "Palermo"
2) "Catania"

redis> GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania"
(integer) 2

redis> GEORADIUS Sicily 15 37 200 km WITHDIST
1) 1) "Palermo"
   2) "190.4424"
2) 1) "Catania"
   2) "56.4413"

redis> GEORADIUS Sicily 15 37 200 km WITHCOORD
1) 1) "Palermo"
   2) 1) "13.361389338970184"
      2) "38.115556395496299"
2) 1) "Catania"
   2) 1) "15.087267458438873"
      2) "37.50266842333162"

redis> GEORADIUS Sicily 15 37 200 km WITHDIST WITHCOORD
1) 1) "Palermo"
   2) "190.4424"
   3) 1) "13.361389338970184"
      2) "38.115556395496299"
2) 1) "Catania"
   2) "56.4413"
   3) 1) "15.087267458438873"
      2) "37.50266842333162"
redis> GEOADD Sicily 13.583333 37.316667 "Agrigento"
(integer) 1

redis> GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania"
(integer) 2

redis> GEORADIUSBYMEMBER Sicily Agrigento 100 km
1) "Agrigento"
2) "Palermo"      

Redis's GEO module is not very good, let's quickly experience it.

Source: Redis Deep Exploration.
http://redisdoc.com/index.html
The content is processed and published by me.

Posted by raan79 on Fri, 17 May 2019 03:42:24 -0700