使用Redis完成微信搖一搖功能

redis提供了地理位置信息(geo)功能,有了他就可以完成附近的人、搖一搖等功能。首先,介紹下geo的相關api。

GEO API

添加地址位置信息

geoadd key longitude latitude member [longitude latitude member …]

  • longitude :經度

  • latitude :緯度

  • member :成員

該命令可以一次添加一個或多個成員

有一些用戶,都在合肥,現在把他們的地理坐標都存放在redis里。

  • 小A在家里看電視,他家的坐標為:117.230279,31.81676

  • 小B在公司加班,公司的坐標為:117.229704,31.824676

  • 小C在出差,他出差的地址坐標為:117.300419,31.696095

  • 小D在家?guī)蓿业牡刂纷鴺藶椋?17.192909,31.732465

  • 小E還在上學,他學校地址坐標為:117.189604,31.838297

127.0.0.1:6379>?geoadd?location?117.230279?31.81676?a?117.229704?31.824676?b (integer)?2 127.0.0.1:6379>?geoadd?location?117.300419?31.696095?c (integer)?1 127.0.0.1:6379>?geoadd?location?117.192909?31.732465?d (integer)?1 127.0.0.1:6379>?geoadd?location?117.189604?31.838297?e (integer)?1

獲取兩個地點的距離

geodist key member1 member2 [unit]

unit有四個單位

  • ‘m’ => 米

  • ‘km’ => 千米

  • ‘mi’ => 英里

  • ‘ft’ => 尺

我們主要會用到米以及千米。

現在我們來看看小A和小B之間的距離

127.0.0.1:6379>?GEODIST?location?a?b?km "0.8821"

可以看到小A和小B之間有0.88千米

再來看看小C和小E之間的距離

127.0.0.1:6379>?GEODIST?location?c?e?km "18.9728"

他們之間相差將近19千米。

獲取地址位置信息

geopos key member [member …]

來看下小D的所在地址的經緯度信息

127.0.0.1:6379>?geopos?location?d 1)?1)?"117.19290822744369507" ???2)?"31.73246441933707018"

獲取指定位置范圍內的地理信息位置集合

georadius key longitude latitude radiusm km|ft|mi [withcoord] [withdist] [withhash] [COUNT count] [asc|desc] [store key] [storedist key] georadiusbymember key member radiusm km|ft|mi [withcoord] [withdist] [withhash] [COUNT count] [asc|desc] [store key] [storedist key]

這兩個命令相比其他的稍顯復雜。我們一起來看看這兩個命令。

這兩個命令功能基本相似,主要的區(qū)別是,第一個命令給出的是具體的經緯度,而第二個命令則只給出了成員名。比如,我想知道成員離合肥大蜀山的距離,因為大蜀山經緯度信息還沒有存放在redis中,所以,我們就需要用第一條命令,將大蜀山的經緯度輸入即可。又如,其他成員離小A所在坐標的距離,那么就可以使用第二條命令,直接輸入成員小A即可。

radiusm 及后面的單位是必填信息,指定在半徑距離多少范圍內搜索。

合肥大蜀山的坐標是117.175571,31.846746

#?查看離大蜀山10km的成員有哪些 127.0.0.1:6379>?GEORADIUS?location?117.175571?31.846746?10?km 1)?"e" 2)?"a" 3)?"b"

可以看到小e、小a及小b離大蜀山比較近,在10km內。

WITHCOORD: 將位置元素的經度和維度也一并返回

127.0.0.1:6379>?GEORADIUS?location?117.175571?31.846746?10?km?withcoord 1)?1)?"e" ???2)?1)?"117.18960374593734741" ??????2)?"31.83829663190295634" 2)?1)?"a" ???2)?1)?"117.23027676343917847" ??????2)?"31.81675910621205361" 3)?1)?"b" ???2)?1)?"117.22970277070999146" ??????2)?"31.8246750403926697"

可以看到,除了給出了成員外,成員的位置信息頁一并給出了

withdist:返回結果中包含離中心節(jié)點位置的距離

127.0.0.1:6379>?GEORADIUS?location?117.175571?31.846746?10?km?withcoord?withdist 1)?1)?"e" ???2)?"1.6252" ???3)?1)?"117.18960374593734741" ??????2)?"31.83829663190295634" 2)?1)?"a" ???2)?"6.1522" ???3)?1)?"117.23027676343917847" ??????2)?"31.81675910621205361" 3)?1)?"b" ???2)?"5.6737" ???3)?1)?"117.22970277070999146" ??????2)?"31.8246750403926697"

可以看到小E離大蜀山1.62千米,小A離大蜀山6.15千米,小B離大蜀山5.67千米。

withhash:這個命令可以忽略不看,基本用不上

COUNT count:指定返回結果的數量。

asc|desc:返回結果按照離中心節(jié)點的距離做升序或者降序。

storedist key:將返回結果離中心節(jié)點的距離保存到指定鍵。

#?獲取離大蜀山100km內范圍的成員,按距離的升序,只需給出最近的4個成員即可 127.0.0.1:6379>?GEORADIUS?location?117.175571?31.846746?100?km?withdist?count?4?asc 1)?1)?"e" ???2)?"1.6252" 2)?1)?"b" ???2)?"5.6737" 3)?1)?"a" ???2)?"6.1522" 4)?1)?"d" ???2)?"12.8164"

實戰(zhàn)

介紹完了上面知識后,就可以來使用php結合redis完成搖一搖找附近的人的功能了。首先,把成員的位置信息給保存下來。

偽代碼如下:

function?addLocation?($key,$member,?$lng,?$lat) { ????$redis->geoadd($key,?$lng,?$lat,?$member); }

然后,獲取附近的人的信息

function?near?( ????$key,? ????$member,? ????$radius,? ????$unit?=?'km',? ????$count?=?0,?? ????$withDist?=?false,? ????$withcoord?=?false,? ????$orderby?=?'ASC' ) { ????$redis?=?new?Redis(); ????$redis->connect('localhost',?6379); ????$options?=?[$orderby]; ????if?($count?>?0)?{ ????????$options['count']?=?$count; ????} ????if?($withDist)?{ ????????$options[]?=?'WITHDIST'; ????} ????if?($withcoord)?{ ????????$options[]?=?'WITHCOORD'; ????} ????$result?=?$redis->geoRadiusByMember($key,?$member,?$radius,?$unit,?$options); ????return?$result; }

使用redis可以大大方便開發(fā)人員,豐富的API可以完成各種各樣的需求,Redis的使用已經成為程序員必備的技能了。

? 版權聲明
THE END
喜歡就支持一下吧
點贊7 分享