從Redis3.2開始,Redis基於geohash和有序集合(zset)提供了地理位置相關功能,用來實現類似微信中附近的人的功能,使用起來十分方便。
Redis Geo模塊大概提供了6個命令,分別為:
1)geoadd:將給定的位置對象(緯度、經度、名字)添加到指定的key;
2)geopos:從key里面返回所有給定位置對象的位置(經度和緯度);
3)geodist:返回兩個給定位置之間的距離;
4)geohash:返回一個或多個位置對象的geohash表示;
5)georadius:以給定的經緯度為中心,返回目標集合中與中心的距離不超過給定最大距離的所有位置對象;
6)georadiusbymember:以給定的位置對象為中心,返回與其距離不超過給定最大距離的所有位置對象。
1.添加地理位置
geoadd key long lat member [longitude latitude member]
命令:將指定的地理空間位置(緯度、經度、名稱)添加到指定的key中。
返回值:添加到sorted set元素的數目,但不包括已更新score的元素。
203.195.205.63:0>geoadd geo:city 121.47 31.23 shanghai 116.40 39.90 beijing 118.78 32.07 nanjing "3"
返回值 3 表示添加成功 3 條記錄。
2.獲取地理位置信息
geopos key member [member ...]
命令描述:從key里返回member的位置(經度和緯度)。
返回值:GEOPOS 命令返回一個數組, 數組中的每個項都由兩個元素組成: 第一個為元素的經度, 而第二個則為元素的緯度。當給定的位置元素不存在時, 對應的數組項為空值。
203.195.205.63:0>geopos geo:city shanghai 203.195.205.63:0>geopos geo:city nanjing
3.獲取兩個地理位置的距離
geodist key member1 member2 [unit]
其中unit為可選參數,可選以下四種,默認 m:
- m:代表單位米
- km:代表單位千米
- mi:代表單位英里
- ft:代表單位尺
203.195.205.63:0>geodist geo:city beijing shanghai "1067378.7564"
4.獲取指定位置內的地理位置集合
命令1:georadius key longitude latitude radius m|km|ft|mi [withcoord] [withdist] [withhash] [count count] 命令2:georadiusbymember key member radius m|km|ft|mi [withcoord] [withdist] [withhash] [count count]
以給定的經緯度為中心,返回鍵包含的位置元素當中,與中心的距離不超過給定最大距離的所有位置元素。
范圍可以使用以下其中一個單位:
m 表示單位為米。
km 表示單位為千米。
mi 表示單位為英里。
ft 表示單位為英尺。
在給定以下可選項時, 命令會返回額外的信息:
WITHDIST: 在返回位置元素的同時,將位置元素與中心之間的距離也一並返回。 距離的單位和用戶給定的范圍單位保持一致。
WITHCOORD: 將位置元素的經度和維度也一並返回。
WITHHASH: 以 52 位有符號整數的形式, 返回位置元素經過原始 geohash 編碼的有序集合分值。 這個選項主要用於底層應用或者調試, 實際中的作用並不大。
命令默認返回未排序的位置元素。 通過以下兩個參數,用戶可以指定被返回位置元素的排序方式:
ASC: 根據中心的位置, 按照從近到遠的方式返回位置元素。
DESC: 根據中心的位置, 按照從遠到近的方式返回位置元素。
在默認情況下, GEORADIUS 命令會返回所有匹配的位置元素。 雖然用戶可以使用 COUNT <count> 選項去獲取前 N 個匹配元素, 但是因為命令在內部可能會需要對所有被匹配的元素進行處理, 所以在對一個非常大的區域進行搜索時, 即使只使用 COUNT 選項去獲取少量元素, 命令的執行速度也可能會非常慢。 但是從另一方面來說, 使用 COUNT 選項去減少需要返回的元素數量, 對於減少帶寬來說仍然是非常有用的。
返回值:
在沒有給定任何 WITH 選項的情況下, 命令只會返回一個像 [“New York”,”Milan”,”Paris”] 這樣的線性(linear)列表。
在指定了 WITHCOORD 、 WITHDIST 、 WITHHASH 等選項的情況下, 命令返回一個二層嵌套數組, 內層的每個子數組就表示一個元素。
在返回嵌套數組時, 子數組的第一個元素總是位置元素的名字。 至於額外的信息, 則會作為子數組的后續元素, 按照以下順序被返回:
以浮點數格式返回的中心與位置元素之間的距離, 單位與用戶指定范圍時的單位一致。
geohash 整數。
由兩個元素組成的坐標,分別為經度和緯度。
203.195.205.63:0>georadius geo:city 121.47 31.23 10000 km withdist 203.195.205.63:0>georadiusbymember geo:city shanghai 10000 km withdist 203.195.205.63:0>georadiusbymember geo:city shanghai 10000 km withcoord
5.刪除地理位置信息
zrem key member
GEO並沒有提供刪除成員的命令,但因為GEO底層實現是zset,所以可以借助 zrem 命令來實現刪除地理位置信息。
203.195.205.63:0>zrem geo:city beijing
6.獲取geohash
geohash key member [member ...]
執行下面的操作可以得到shanghai 的geohash值:
203.195.205.63:0>geohash geo:city shanghai 1) "wtw3sj5zbj0"
GEO的數據類型是zset,Redis將所有地理位置信息的geohash存在zset中
geohash字符串越長表示地理位置精度越高
兩個geohash字符串越相似,兩個位置距離越近
geohash和經緯度之間有着一一對應的關系
Redis GEO的命令都是基於geohash來實現的
總結
Redis GEO是一個很新的數據結構,使用geohash和zset實現。
可以方便我們關於地理位置的存取,在特定的使用場景還是很有價值的。