redis geographic位置数据处理

redis GEO位置数据处理

GEO功能介绍

Redis 3.2之后的版本,新增了存储地理位置信息的功能,即 GEO(英文全称 geographic),命令会将给定的坐标元素(纬度、经度、名字)添加到指定的键里面, 这些数据就会以有序集合的形式被储,它的底层通过 Redis 有序集合(zset)实现。不过 Redis GEO 并没有与 zset 共用一套的命令,而是拥有自己的一套命令。

Redis GEO 提供了 6 个常用命令:

  • GEOADD :将坐标信息添加到指定的键里面
  • GEOPOS :根据地点的名称返回对应的经纬度。集合中不存在时,返回数据为空
  • GEODIST :返回两个给定位置之间的距离。如果两个位置之间的其中一个不存在, 那么命令返回空值。
  • GEORADIUS :以给定的经纬度为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素。
  • GEORADIUSBYMEMBER :这个命令和 GEORADIUS 命令一样, 都可以找出位于指定范围内的元素, 但是GEORADIUSBYMEMBER的中心点是由给定的位置元素决定的, 而不是像GEORADIUS 那样, 使用输入的经度和纬度来决定中心点。
  • GEOHASH :返回一个或多个位置元素的哈希字符串,该字符串具有唯一 ID 标识,它与给定的位置元素一一对应
  • ZREM :通过有序集合的 zrem 命令实现对地理位置信息的删除。


命令实例

GEOADD

将指定的地理空间位置(纬度、经度、名称)添加到指定的 key 中。语法格式如下:

GEOADD key longitude latitude member [longitude latitude member ...]
  • longitude :位置地点所处的经度;
  • latitude :位置地点所处的纬度;
  • member :位置名称。

将给定的经纬度的位置名称(纬度、经度、名字)与 key 相对应,这些数据以有序集合的形式进行储存。

GEOADD命令以标准的x,y形式接受参数, 所以用户必须先输入经度,然后再输入纬度。GEOADD命令能够记录的坐标数量是有限的,如果位置非常接近两极(南极/北极)区域,那么将无法被索引到。因此当您输入经纬度时,需要注意以下规则:
有效的经度介于 -180 度至 180 度之间。
有效的纬度介于 -85.05112878 度至 85.05112878 度之间。
注意:如果您输入一个超出范围的经纬度时,GEOADD 命令将返回一个错误。

示例演示如下:
添加城市地理位置

127.0.0.1:6379> geoadd city 116.20 39.56 beijing 120.52 30.40 shanghai
(integer) 2

查询城市地理位置

127.0.0.1:6379> GEOPOS city beijing shanghai
1) 1) "116.19999736547470093"
   2) "39.56000019952067248"
2) 1) "120.52000075578689575"
   2) "30.39999952668997452"

GEODIST

该命令用于获取两个地理位置间的距离。返回值为双精度浮点数,其语法格式如下:

GEODIST key m1 m2 [unit]

参数 unit 是表示距离单位,取值如下所示:

  • m 表示单位为米;
  • km 表示单位为千米;
  • mi 表示单位为英里;
  • ft 表示单位为英尺。

注意:如果没有指出距离单位,那么默认取值为m。示例如下:

127.0.0.1:6379> GEODIST city beijing shanghai
"1091868.8970"
127.0.0.1:6379> GEODIST city beijing shanghai km
"1091.8689"
127.0.0.1:6379> GEODIST city beijing shanghai mi
"678.4576"
注意:计算举例时存在 0.5% 左右的误差,这是由于 Redis GEO 把地球假设成了完美的球体。

GEORADIUS

以给定的经纬度为中心,计算出 key 包含的地理位置元素与中心的距离不超过给定最大距离的所有位置元素,并将其返回。

GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC]

参数说明:

WITHDIST :在返回位置元素的同时, 将位置元素与中心之间的距离也一并返回。
WITHCOORD :返回位置元素的经度和维度。
WITHHASH :采用 GEOHASH 对位置元素进行编码,以 52 位有符号整数的形式返回有序集合的分值,该选项主要用于底层调试,实际作用不大。
COUNT:指定返回位置元素的数量,在数据量非常大时,可以使用此参数限制元素的返回数量,从而加快计算速度。

注意:该命令默认返回的是未排序的位置元素。通过 ASC 与 DESC 可让返回的位置元素以升序或者降序方式排列。

命令应用示例如下:
添加几个地理位置元素

127.0.0.1:6379> GEOADD city 106.45 29.56 chongqing 120.33 36.06 qingdao 103.73 36.03 lanzhou
(integer) 3
127.0.0.1:6379> GEOADD city 106.71 26.56 guiyang
(integer) 1
//以首都的坐标为中心,计算各个城市距离首都的距离,最大范围设置为1500km
//同时返回距离,与位置元素的经纬度
127.0.0.1:6379> GEORADIUS city 116.41 39.91 1500 km WITHCOORD WITHDIST
1) 1) "chongqing"
   2) "1465.5618"
   3) 1) "106.4500012993812561"
      2) "29.56000053864853072"
2) 1) "lanzhou"
   2) "1191.2793"
   3) 1) "103.72999995946884155"
      2) "36.03000049919800318"
3) 1) "shanghai"
   2) "1121.4882"
   3) 1) "120.52000075578689575"
      2) "30.39999952668997452"
4) 1) "qingdao"
   2) "548.9304"
   3) 1) "120.3299984335899353"
      2) "36.05999892411877994"
5) 1) "beijing"
   2) "42.8734"
   3) 1) "116.19999736547470093"
      2) "39.56000019952067248"

GEORADIUSBYMEMBER

根据给定的地理位置坐标(即经纬度)获取指定范围内的位置元素集合。其语法格式如下:

GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DES]

参数说明:
m :米,默认单位;
km :千米(可选);
mi :英里(可选);
ft :英尺(可选);
ASC:根据距离将查找结果从近到远排序;
DESC:根据距离将查找结果从远到近排序。

该命令与 GEORADIUS 命令相似,不过它选择的中心的是具体的位置元素,而非经纬度坐标。示例如下:
//以贵阳为中心,最大距离不超过900km

127.0.0.1:6379> GEORADIUSBYMEMBER city guiyang 900 km WITHCOORD WITHDIST
1) 1) "guiyang"
   2) "0.0000"
   3) 1) "106.70999854803085327"
      2) "26.56000089385899798"
//只有重庆符合条件
2) 1) "chongqing"
   2) "334.6529"
   3) 1) "106.4500012993812561"
      2) "29.56000053864853072"

GEOHASH

返回一个或多个位置元素的哈希字符串,该字符串具有唯一 ID 标识,它与给定的位置元素一一对应。示例如下:

127.0.0.1:6379> GEOHASH city lanzhou beijing shanghai
1) "wq3ubrjcun0"
2) "wx49h1wm8n0"
3) "wtmsyqpuzd0"

ZREM

用于删除指定的地理位置元素,示例如下:

127.0.0.1:6379> zrem city beijing shanghai
(integer) 2