Redis 高级数据结构 GEO

    Redis 3.2版本提供了GEO(地理信息定位)功能,支持存储地理位置信息用来实现诸如附近位置、摇一摇这类依赖于地理位置信息的功能。
    地图元素的位置数据使用二维的经纬度表示,经度范围(-180, 180],纬度范围(-90,90],纬度正负以赤道为界,北正南负,经度正负
以本初子午线(英国格林尼治天文台) 为界,东正西负。
    业界比较通用的地理位置距离排序算法是GeoHash 算法,Redis 也使用GeoHash算法。GeoHash算法将二维的经纬度数据映射到一维的
整数,这样所有的元素都将在挂载到一条线上,距离靠近的二维坐标映射到一维后的点之间距离也会很接近。当我们想要计算「附近的人时」,
首先将目标位置映射到这条线上,然后在这个一维的线上获取附近的点就行了。
   在Redis里面,经纬度使用52位的整数进行编码,放进了zse 里面,zset的value 是元素的 key,score是GeoHash的52位整数值。

操作命令

1、增加地理位置信息 geoadd key longitude latitude member [longitude latitude member …]

longitude、latitude、member分别是该地理位置的经度、纬度、成员。例如下面有5个城市的经纬度。

城市 经度 纬度 成员

北京 116.28 39.55 beijing

天津 117.12 39.08 tianjin

石家庄 114.29 38.02 shijiazhuang

唐山 118.01 39.38 tangshan

保定 115.29 38.51 baoding

cities:locations 是上面5个城市地理位置信息的集合,现向其添加北京的地理位置信息:

 返回结果代表添加成功的个数,如果cities:locations没有包含beijing,那么返回结果为1,如果已经存在则返回0127.0.0.1:6379> geoadd cities:locations 116.28 39.55 beijing
	(integer) 1
	127.0.0.1:6379> geoadd cities:locations 116.28 39.55 beijing
	(integer) 0
 如果需要更新地理位置信息,仍然可以使用geoadd命令,虽然返回结果为0
    127.0.0.1:6379> geoadd cities:locations116.28 39.54 beijing
	(integer) 0
	127.0.0.1:6379> geopos cities:localhosts beijing
	1) 1) "116.28000229597091675"
	   2) "39.54000124957348561"
	127.0.0.1:6379> geoadd cities:locations116.28 39.55 beijing
	(integer) 0
	127.0.0.1:6379> geopos cities:localhosts beijing
	1) 1) "116.28000229597091675"
	   2) "39.5500007245470826"

geoadd命令可以同时添加多个地理位置信息:

127.0.0.1:6379> geoadd cities:locations 117.12 39.08 tianjin 114.29 38.02 shijiazhuang 118.01 39.38 tangshan 115.29 38.51 baoding
(integer) 4
127.0.0.1:6379>

2、获取地理位置信息 geopos key member [member …]

	127.0.0.1:6379> geopos cities:locations tianjin
	1) 1) "117.12000042200088501"
	   2) "39.0800000535766543"

3、 获取两个地理位置的距离。geodist key member1 member2 [unit]

其中unit代表返回结果的单位,包含以下四种:

  • m (meters)代表米。
  • km (kilometers)代表公里。
  • mi (miles)代表英里。
  • ft(feet)代表尺。

举例操作用于计算天津到北京的距离,并以公里为单位:

127.0.0.1:6379> geodist cities:locations tianjin beijing km
"89.2061"

4、 获取指定位置范围内的地理信息位置集合

georadius key longitude latitude radius m|km|ft|mi [withcoord][withdist]
[withhash][COUNT count] [ascldesc] [store key] [storedist key]

georadiusbymember key member radius m|km|ft|mi  [withcoord][withdist]
[withhash] [COUNT count][ascldesc] [store key] [storedist key]
    georadius  和  georadiusbymember两个命令的作用是一样的,都是以一个地理位置为中心算出指定半径内的其他地理信息位置,
不同的是georadius命令的中心位置给出了具体的经纬度,georadiusbymember只需给出成员即可。其中radius  m | km |ft |mi是
必需参数,指定了半径(带单位)。

	这两个命令有很多可选参数,如下所示:
	
	withcoord:返回结果中包含经纬度。
	
	withdist:返回结果中包含离中心节点位置的距离。
	
	withhash:返回结果中包含geohash,有关geohash后面介绍。
	
	COUNT count:指定返回结果的数量。
	
	asc l desc:返回结果按照离中心节点的距离做升序或者降序。
	
	store key:将返回结果的地理位置信息保存到指定键。
	
	storedist key:将返回结果离中心节点的距离保存到指定键。

操作计算五座城市中,距离北京150公里以内的城市:

	127.0.0.1:6379> georadiusbymember cities:locations beijing 150 km
	1) "beijing"
	2) "tianjin"
	3) "tangshan"
	4) "baoding"
	127.0.0.1:6379>

5、 获取geohash geohash key member [member …]

Redis使用geohash将二维经纬度转换为一维字符串,下面操作会返回beijing的geohash值。

127.0.0.1:6379> geohash cities:locations beijing
1) "wx48ypbe2q0"

字符串越长,表示的位置更精确,geohash长度为9时,精度在2米左右,geohash长度为8时,精度在20米左右。

两个字符串越相似,它们之间的距离越近,Redis 利用字符串前缀匹配算法实现相关的命令。

geohash编码和经纬度是可以相互转换的。

6、 删除地理位置信息 zrem key member

GEO没有提供删除成员的命令,但是因为GEO的底层实现是zset,所以可以借用zrem命令实现对地理位置信息的删除。

	127.0.0.1:6379> type  cities:locations
	zset
	127.0.0.1:6379> geopos cities:locations tianjin
	1) 1) "117.12000042200088501"
	   2) "39.0800000535766543"
	127.0.0.1:6379> zrem cities:locations tianjin
	(integer) 1
	127.0.0.1:6379> geopos cities:locations tianjin
	1) (nil)
	127.0.0.1:6379> geopos cities:locations beijing
	1) 1) "116.28000229597091675"
	   2) "39.5500007245470826"

你可能感兴趣的:(redis,redis,数据结构,数据库)