redis地理操作

redis 从 3.2.0 版本开始提供了对地理位置的支持,相关的命令有 GEOADDGEOHASHGEOPOSGEODISTGEORADIUSGEORADIUSBYMEMBER,本文简单介绍下这些命令的用法。

reids 的地理位置坐标使用 soted set 存储,它使用了一项叫做 Geohash 的技术,将经度和维度的二进制位交叉存储为一个 52 位的整数。

在距离计算上,使用的是 Haversine 算法,它假定地球是一个球体。然而地球并不是一个完美的球体,因此距离计算并不是十分精确,极端情况下可能会有 0.5% 的误差。

在覆盖范围上,不能覆盖靠近南、北极的区域,在 EPSG:900913 / EPSG:3785 / OSGEO:41001 中给出了具体的有效范围:

  • 有效的经度范围为 -180 到 180
  • 有效的维度范围为 -85.05112878 到 85.05112878

使用方法

GEOADD 命令用于添加地理位置坐标,添加好坐标点之后,可以使用 GEORADIUSGEORADIUSBYMEMBER 命令根据查询指定半径范围内的点。GEOPOS 用于查询已存储点的坐标,GEODIST 用于查询两个坐标点之间的距离,GEOHASH 用于查询已存储点的 Geohash 值。

GEOADD

用于添加坐标点。它的语法为:

1
GEOADD key longitude latitude member [longitude latitude member ...]

示例:往 key 为 metro2 的集合中添加 WestNanJingRoadJingAnTemple 两个点

1
2
3
4
127.0.0.1:6379> GEOADD metro2 121.459984 31.229945 WestNanJingRoad
(integer) 1
127.0.0.1:6379> GEOADD metro2 121.44623 31.223119 JingAnTemple
(integer) 1

GEOPOS

用于查询已有成员的坐标。它的语法为:

1
GEOPOS key member [member ...]

示例:查询 WestNanJingRoad 的坐标,返回经纬度

1
2
3
127.0.0.1:6379> GEOPOS metro2 WestNanJingRoad
1) 1) "121.45998626947402954"
2) "31.22994581061349351"

查询 ZhongShanPark 的坐标,返回空

1
2
127.0.0.1:6379> GEOPOS metro2 ZhongShanPark
1) (nil)

GEODIST

用于查询两个坐标点之间的距离。它的语法为:

1
GEODIST key member1 member2 [unit]

示例:查询 WestNanJingRoadJingAnTemple 之间的距离,返回结果单位为 m

1
2
127.0.0.1:6379> GEODIST metro2 WestNanJingRoad JingAnTemple
"1512.5623"

指定返回单位为 km

1
2
127.0.0.1:6379> GEODIST metro2 WestNanJingRoad JingAnTemple km
"1.5126"

GEORADIUS

指定坐标点,查询周围指定半径范围内的点。它的语法为:

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

示例:查询距离 121.46096 31.231055 500 米范围内是否有坐标点

1
2
127.0.0.1:6379> GEORADIUS metro2 121.46096 31.231055 500 m
1) "WestNanJingRoad"

缩小为 100 米,再次查询

1
2
127.0.0.1:6379> GEORADIUS metro2 121.46096 31.231055 100 m
(empty list or set)

GEORADIUSBYMEMBER

GEORADIUS 类似,区别是不能随意指定坐标点,只能指定集合中已有的成员。它的语法为:

1
GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]

示例:查询 JingAnTemple 2km 范围内的点,返回结果包括它自己

1
2
3
127.0.0.1:6379> GEORADIUSBYMEMBER metro2 JingAnTemple 2 km
1) "JingAnTemple"
2) "WestNanJingRoad"

GEOHASH

返回指定成员的 Geohash 值。它的语法为:

1
GEOHASH key member [member ...]

示例:查询 WestNanJingRoad 的 Geohash 值

1
2
127.0.0.1:6379> GEOHASH metro2 WestNanJingRoad
1) "wtw3evhrwg0"

参考

https://redis.io/commands