在 Redis 的 3.2 版本中加入了地理空间(geospatial)以及索引半径查询的功能,这在需要地理位置功能的应用上或许可以一展身手。Redis 的地理空间(geospatial)索引允许您存储地理坐标(经纬度)并搜索它们,此数据结构可用于查找给定半径或边界框内的邻近点。
当我们把某个具体的位置信息(经度,纬度,名称)添加到指定的 key 中,数据将会用一个 sorted set(有序集合)存储,以便稍后能使用 GEORADIUS 和 GEORADIUSBYMEMBER 命令来根据半径来查询位置信息。
(1)有效的经度是 -180 度到 180 度当我们使用 GEOADD 命令添加坐标时,其参数使用标准的 x,y 形式。所以经度(longitude)必须放在纬度(latitude)之前,对于可被索引的坐标位置是有一定限制条件的:非常靠近极点的位置是不能被索引的, 在 EPSG:900913 / EPSG:3785 / OSGEO:41001 指定如下:
(2)有效的纬度是 -85.05112878 度到 85.05112878 度
注意:
(1)如果使用了超出有效范围的经纬度,此命令会返回一个错误。
(2)之所以没有 GEODEL 命令,是因为你可以用 ZREM 来删除一个元素,GEO 索引结构实际上就是一个有序集合(sorted set)。
假设你正在建立一个移动应用程序,让你找到离你当前位置最近的所有电动汽车充电站。
(1)将几个地点添加到一个地理空间索引中,如下:
127.0.0.1:6379> GEOADD locations:ca -122.27652 37.805186 station:1 (integer) 1 127.0.0.1:6379> GEOADD locations:ca -122.2674626 37.8062344 station:2 (integer) 1 127.0.0.1:6379> GEOADD locations:ca -122.2469854 37.8104049 station:3 (integer) 1
(2)找到给定地点的 5 公里半径内的所有地点,并返回每个地点的距离。如下:
127.0.0.1:6379> GEOSEARCH locations:ca FROMLONLAT -122.2612767 37.7936847 BYRADIUS 5 km WITHDIST 1) 1) "station:1" 2) "1.8523" 2) 1) "station:2" 2) "1.4979" 3) 1) "station:3" 2) "2.2441"
下面列出了 Redis Geospatial 的基本命令。下面是几个需要用到的经纬度:
北京市 116.404188,39.914687 天津市 117.225913,39.020948 成都市 104.071846,30.58706
添加一个或多个地理位置元素到一个 key 中。语法如下 :
GEOADD key longitude latitude member [longitude latitude member ...]
实例:
127.0.0.1:6379> geoadd locations 116.404188 39.914687 beijingshi (integer) 1 127.0.0.1:6379> geoadd locations 117.225913 39.020948 tianjinshi (integer) 1 127.0.0.1:6379> geoadd locations 104.071846 30.58706 chengdushi (integer) 1
GEODIST 返回一个key中指定两个位置之间的距离。语法如下 :
GEODIST key member1 member2 [unit]
注意:unit 可以指定长度单位:m、km、ft 等,默认为 m。
实例:
127.0.0.1:6379> geodist locations beijingshi tianjinshi km "121.9007" 127.0.0.1:6379> geodist locations beijingshi chengdushi km "1523.9951"
返回一个或多个位置元素的 Geohash 表示,Geohash 是一种经纬度散列算法。语法如下 :
GEOHASH key member [member ...]
实例:
127.0.0.1:6379> geohash locations beijingshi 1) "wx4g0f4zyh0" 127.0.0.1:6379> geohash locations beijingshi chengdushi 1) "wx4g0f4zyh0" 2) "wm6n00ny9c0"
返回一个或多个位置的经纬度信息,由于采用了 geohash 算法,返回的经纬度和添加时的数据可能会有细小误差。语法如下 :
GEOPOS key member [member ...]
实例:
127.0.0.1:6379> geopos locations chengdushi 1) 1) "104.07184749841690063" 2) "30.58705941352803137" 127.0.0.1:6379> geopos locations chengdushi beijingshi 1) 1) "104.07184749841690063" 2) "30.58705941352803137" 2) 1) "116.40418857336044312" 2) "39.91468626606813075"
以给定位置为中心,半径不超过给定半径的附近所有位置。语法如下 :
GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count]
其中,半径的单位含义如下:
m 表示米。
km 表示千米。
ft 表示英寸。
mi 表示英里。
实例:
# 查询北京市(经纬度:116.404188,39.914687)附近 200公里(km)的其他坐标位置 127.0.0.1:6379> georadius locations 116.404188 39.914687 200 km 1) "beijingshi" 2) "tianjinshi"
GEORADIUSBYMEMBER 和 GEORADIUS 相似,只是中心点不是指定经纬度,而是指定已添加的某个位置作为中心。语法如下 :
GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count]
实例:
# 查询北京市(经纬度:116.404188,39.914687)附近 200公里(km)的其他坐标位置 127.0.0.1:6379> georadiusbymember locations beijingshi 200 km 1) "beijingshi" 2) "tianjinshi"
更多命令请访问 https://redis.io/commands 进行参考。