Redis 數據類型:Geo

本文我們將學習 Redis Geo 數據類型,並瞭解它如何在需要需要位置服務的應用中使用,例如網約車。

介紹

Redis GEO 是 Redis 3.2 版本中新增的數據類型,主要用於存儲地理位置信息以及對存儲的信息進行操作。

在日常生活中,我們越來越依賴於搜索附近的購物中心和餐館。旅行時,我們通過出租車叫車應用叫出租車。這一切都離不開位置服務(Location-Based Service,LBS)的應用。

LBS 應用訪問的數據是一組與人或物體相關的經緯度信息,需要能夠查詢相鄰的經緯度範圍。 GEO 非常適合在 LBS 服務場景中應用。

內部實現

GEO 直接使用有序集合(Sorted Set)實現,本身並沒有設計新的底層數據結構。

GEO 類型使用 GeoHash 編碼方法實現從經緯度到有序集合(Sorted Set)中元素權重分數的轉換。 其中的兩個關鍵機制是 "將二維地圖劃分爲區間" 和 "對區間進行編碼"。 當一組經緯度落入某個區間後,就用該區間的編碼值來表示,編碼值就作爲該元素在有序集合(Sorted Set)中的權重分值。

這樣,我們就可以將經緯度保存到有序集合(Sorted Set)中,利用有序集合(Sorted Set)提供的 “按權重有序範圍搜索” 的特性來實現 LBS 服務中經常使用的 “搜索附近” 的需求。

常用命令

  1. 添加地理位置

命令:geoadd key longitude latitude member [longitude latitude member ...]

該命令支持一次添加一個或多個位置。

  1. 查詢位置信息

命令:geopos key member [member ...]

該命令支持查看一個或多個的位置信息。

  1. 距離計算

命令:geodist key member1 member2 [unit]

  1. 查詢某一地點內其它成員信息

命令:georadius key longtitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC]

  1. 查詢位置的哈希值

命令:geohash key member [member ...]

  1. 刪除地理位置

命令:zrem key member [member ...]

下面我們通過一個小例子來看看這些命令的使用。

基本使用

  1. 添加地理位置

以下從騰訊地圖獲取了三個地理位置:

**動車站:**24.973462(緯度),118.567344(經度)

**商場:**24.969067(緯度),118.56889(經度)

**公園:**24.953205(緯度),118.540218(經度)

首先,將它們添加到 Redis 中:

127.0.0.1:6379> geoadd site 118.567344 24.973462 Subway:Station
(integer) 1
127.0.0.1:6379> geoadd site 118.56889 24.969067 Mall
(integer) 1
127.0.0.1:6379> geoadd site 118.540218 24.953205 Park
(integer) 1
127.0.0.1:6379>
  1. 查詢位置信息

查看剛剛添加的商場的地理位置。

127.0.0.1:6379> geopos site Mall
1) 1) "118.56889218091964722"
   2) "24.96906794987295086"
  1. 查詢某一地點內其它成員信息

計算以下商場到公園的距離是多少米。

127.0.0.1:6379> geodist site Mall Park m
"3387.0769"

可以看到,兩個位置的直線距離是 3387.0769 米。

unit 參數代表統計單位,可以設置以下值:

m:米,默認單位;

km:以公里爲單位;

mi:以英里爲單位;

ft:以英尺爲單位。

  1. 查詢某一地點內其它成員信息

我們來查看指定經緯度附近範圍內的地址信息。假設以商場地址作爲輸入,看看 1 公里以內的結果:

127.0.0.1:6379> georadius site 118.56889 24.969067 1 km
1) "Mall"
2) "Subway:Station"

可以看到,動車站在商場的 1 公里範圍內。

以下還有一些可選的參數:

4.1 WITHCOORD

描述:返回滿足條件的位置的經緯度信息。

127.0.0.1:6379> georadius site 118.56889 24.969067 1 km withcoord
1) 1) "Mall"
   2) 1) "118.56889218091964722"
      2) "24.96906794987295086"
2) 1) "Subway:Station"
   2) 1) "118.56734186410903931"
      2) "24.97346315636324476"

4.2 WITHDIST

描述:返回滿足位置與查詢位置之間的直線距離。

127.0.0.1:6379> georadius site 118.56889 24.969067 1000 m withdist
1) 1) "Mall"
   2) "0.2440"
2) 1) "Subway:Station"
   2) "513.2797"

4.3 WITHHASH

描述:返回滿足條件的 hash。

127.0.0.1:6379> georadius site 118.56889 24.969067 1000 m withdist
1) 1) "Mall"
   2) (integer) 4049596625932254
2) 1) "Subway:Station"
   2) (integer) 4049596638315160

4.4 COUNT count

描述:指定滿足條件的位置數量。

例如,指定返回符合條件的信息,代碼如下:

127.0.0.1:6379> georadius site 118.56889 24.969067 1000 m count 1
1) "Mall"

127.0.0.1:6379> georadius site 118.56889 24.969067 1000 m count 2
1) "Mall"
2) "Subway:Station"

4.5 ASC|DESC

描述:按由近到遠 | 由遠到近返回。

127.0.0.1:6379> georadius site 118.56889 24.969067 1000 m desc
1) "Subway:Station"
2) "Mall"

127.0.0.1:6379> georadius site 118.56889 24.969067 1000 m asc
1) "Mall"
2) "Subway:Station"

當然,上面的可選參數也可以一起使用,比如下面的代碼:

127.0.0.1:6379> georadius site 118.56889 24.969067 1000 m desc
1) 1) "Subway:Station"
   2) "513.2797"
2) 1) "Mall"
   2) "0.2440"
  1. 查詢位置的哈希值
127.0.0.1:6379> geohash site Mall
1) "wskq417pr70"

該命令支持一次查詢一個或多個地址的哈希值。

  1. 刪除位置
127.0.0.1:6379> zrem site Mall
(integer) 1

# 重複查詢返回 null
127.0.0.1:6379> geohash site Mall
1) (nil)

應用場景

網約車

該數據類型主要可以用於查找附近的人、附近的地址等功能。

我們以網約車場景爲例,介紹如何使用 GEO 命令來實現該功能。

假設一輛車的 ID 爲 520,經緯度爲 (114.17351602367509, 22.324873810295088) ,對方車的 ID 是521 ,經緯度是 (114.16907428570298, 22.324223743873898) ,我們可以用一個 GEO 集合來保存所有車輛的經緯度,集合的 key 是 taxi:locations。

執行以下命令,將 ID 號爲520521的出租車當前經緯度位置存儲到 GEO 集合中:

127.0.0.1:6379> geoadd taxi:locations 114.17351602367509 22.324873810295088 520 114.16907428570298 22.324223743873898 521
(integer) 2

當用戶想要找到附近的在線出租車時,應用程序可以使用 GEORADIUS 命令。

例如,當用戶叫車時,應用程序將執行以下命令。 Redis 會根據輸入用戶的經緯度信息查找以該經緯度爲中心 5 公里範圍內的出租車信息 (114.16848419961286, 22.322288413685154) 並將其返回給用戶。

127.0.0.1:6379> GEORADIUS taxi:locations 114.16848419961286 22.322288413685154 5 km withdist ASC COUNT 5
1) 1) "521"
   2) "0.2235"
2) 1) "520"
   2) "0.5920"
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/hj3pMPXIZQ5vlE7Qr5epHw