查詢附近的人或者是附近的商家是一個(gè)實(shí)用且常用的功能,比如微信中“附近的人”或是美團(tuán)外賣中“附近商家”等幸斥,如下圖所示:
那它是如何實(shí)現(xiàn)的呢匹摇?我們本文就一起來(lái)看。
我們本文的面試題是睡毒,使用 Redis 如何實(shí)現(xiàn)查詢附近的人来惧?
典型回答
在說(shuō)如何實(shí)現(xiàn)地理位置查詢之前,首先我們需要搞清楚地理位置查詢的基礎(chǔ)知識(shí)演顾。
我們所處的任何位置都可以用經(jīng)度和緯度來(lái)標(biāo)識(shí)供搀,經(jīng)度的范圍 -180 到 180隅居,緯度的范圍為:-90 到 90。緯度以赤道為界葛虐,赤道以南為負(fù)數(shù)胎源,赤道以北為正數(shù);經(jīng)度以本初子午線 (英國(guó)格林尼治天文臺(tái)) 為界屿脐,東邊為正數(shù)涕蚤,西邊為負(fù)數(shù)。這樣我們所處的位置才能在地球上被標(biāo)注出來(lái)的诵,這也成為了我們能夠查詢出兩點(diǎn)之間距離的基礎(chǔ)万栅,如下圖所示:從而讓查詢附近的人變得簡(jiǎn)單了,我們只需要查詢出附近幾個(gè)點(diǎn)和自己的距離西疤,再進(jìn)行排序就可以實(shí)現(xiàn)查詢附近人的功能了烦粒,然而使用 Redis 讓這一切更簡(jiǎn)單了,Redis 為我們提供了專門用來(lái)存儲(chǔ)地理位置的類型 GEO代赁,我們使用它以及它所內(nèi)置的方法就可以輕松的實(shí)現(xiàn)查詢附近的人了扰她。
我們可以使用 Redis 3.2 版本中新增了 GEO 類型,以及它的 georadius 命令來(lái)實(shí)現(xiàn)查詢附近的人芭碍,例如我們可以先添加幾個(gè)人的位置信息徒役,實(shí)現(xiàn)命令如下:
127.0.0.1:6379> geoadd site 116.404269 39.913164 tianan
(integer) 1
127.0.0.1:6379> geoadd site 116.36 39.922461 yuetan
(integer) 1
127.0.0.1:6379> geoadd site 116.499705 39.874635 huanle
(integer) 1
127.0.0.1:6379> geoadd site 116.193275 39.996348 xiangshan
(integer) 1
添加位置信息我們需要使用 geoadd 命令,它的語(yǔ)法為:geoadd key longitude latitude member [longitude latitude member ...]
其中:
- longitude 表示經(jīng)度窖壕;
- latitude 表示緯度忧勿;
- member 是為此經(jīng)緯度起的名字。
此命令支持一次添加一個(gè)或多個(gè)位置信息艇拍。
我們?cè)诓樵兡硞€(gè)人(某個(gè)經(jīng)緯度)附近的人狐蜕,實(shí)現(xiàn)命令如下:
127.0.0.1:6379> georadius site 116.405419 39.913164 5 km
1) "tianan"
2) "yuetan"
從上述結(jié)果中可以看出在經(jīng)緯度為 116.405419,39.913164 的附近五公里范圍內(nèi)有兩個(gè)人“tianan”和“月壇”宠纯,于是查詢附近人的功能就算實(shí)現(xiàn)完成了卸夕。
georadius 命令的相關(guān)語(yǔ)法為: georadius key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC]
georadius 命令可以使用以下其中一個(gè)單位:
- m 表示單位為米;
- km 表示單位為千米婆瓜;
- mi 表示單位為英里快集;
- ft 表示單位為英尺;
georadius 命令包含的可選參數(shù)如下廉白。
① WITHCOORD
說(shuō)明:返回滿足條件位置的經(jīng)緯度信息个初。 示例代碼:
127.0.0.1:6379> georadius site 116.405419 39.913164 5 km withcoord
1) 1) "tianan"
2) 1) "116.40426903963088989"
2) "39.91316289865137179"
2) 1) "yuetan"
2) 1) "116.36000186204910278"
2) "39.92246025586381819"