我們知道在移動(dòng)互聯(lián)網(wǎng)時(shí)代,各種如打車、交友等APP軟件都有一個(gè)查找定位附近的人的功能,但是對(duì)于我們程序開發(fā)員來說怎樣能快速高效的實(shí)現(xiàn)這個(gè)功能?深圳APP開發(fā)公司本文就這個(gè)問題分享我們工程師日常的開發(fā)經(jīng)驗(yàn)。我們知道LBS主要用于查找附近的人(或者某個(gè)事物),其常見的使用情景如圖9-32所示。
查找附近的人在程序中的處理流程是:數(shù)據(jù)庫(kù)的用戶信息中有個(gè)地理坐標(biāo)字段,己知某個(gè)用戶的地理坐標(biāo),把這個(gè)坐標(biāo)定范圍內(nèi)(例如500米內(nèi))的其他地理坐標(biāo)找出來。APP開發(fā)公司下面介紹3種實(shí)現(xiàn)查找附近的人的方案:
1.MySQL的空間數(shù)據(jù)庫(kù)解決方案
從MySQL 4.1開始就引入了系列空間擴(kuò)展,使其具備了定的空間處理能力
簡(jiǎn)單點(diǎn)來說,就是MySQL已經(jīng)可以把地理坐標(biāo)的數(shù)據(jù)當(dāng)成種獨(dú)立的數(shù)據(jù)類型,而且提供了相關(guān)的空間函數(shù)(例如查找個(gè)矩形范圍內(nèi)
的坐標(biāo))給開發(fā)者直接調(diào)用。
2.geohash解決方案
geohash編碼,就是通過算法把地理坐標(biāo)轉(zhuǎn)換成個(gè)值,簡(jiǎn)單點(diǎn)來說就是把二維坐標(biāo)轉(zhuǎn)換成一個(gè)字符串,但這個(gè)字符串并不是毫無意義。
geohash有以下的特點(diǎn)。
(1) geohash把地理坐標(biāo)轉(zhuǎn)換為字符串
如圖9-33所示,展示了“國(guó)家數(shù)字家庭應(yīng)用示范產(chǎn)業(yè)基地”的地圖
在上圖中,“國(guó)家數(shù)字家庭應(yīng)用示范產(chǎn)業(yè)基地”從地圖上得到的坐標(biāo)是“113. 39175.23.061784”,這個(gè)坐標(biāo)同時(shí)也可以用geohash值“wsOehq32ekOu”表示。用geohash值表示坐標(biāo)有以下兩個(gè)好處。
·避免泄露用戶的真實(shí)坐標(biāo),保護(hù)隱私(雖然國(guó)內(nèi)用戶并不看重這個(gè)問題)。
·geohash值是個(gè)字符串,方便緩存。在下面會(huì)提到一個(gè)案例用緩存geohash值來快速搜索。如果使用坐標(biāo)值就不方便緩存
(2)坐標(biāo)的geohash值越相似,意味著距離越相近
(3) geohash值越長(zhǎng),表示的范圍越精確。如表9-5所示,展示Tgeohash值的長(zhǎng)度和相應(yīng)的表示范圍的關(guān)系
從上表可看出,當(dāng)geohash值的長(zhǎng)度為6時(shí),對(duì)應(yīng)坐標(biāo)的距離大約是相距0.61千米,“查找附近的人”這個(gè)功能平常就查找l公里范圍內(nèi),按照geohash值的長(zhǎng)度為6查找就差不多。
但是使用geohash查找附近的人需要注意如圖9-34所示的例子。
在圖9-34中用geohash查找a點(diǎn)附近的點(diǎn)時(shí),由于a和b是在同到a點(diǎn)的距離和b點(diǎn)到a點(diǎn)的距離差不多,為了取得更精確的結(jié)果,一個(gè)區(qū)域內(nèi),根據(jù)geohash算法認(rèn)為a附近只有b。但在圖9-34上可看到,c點(diǎn)除了取目標(biāo)點(diǎn)的geohash值外,還需要使用a點(diǎn)周圍8個(gè)區(qū)域的geohash值。
基于geohash值是字符串的特性,查找附近坐標(biāo)的時(shí)候用SQL中模糊查詢LIKE“wsOehh%”查找geohash值“wsOehh”附近的所有地點(diǎn)非常方便。
APP開發(fā)公司的程序員早期做過的產(chǎn)品中,有一個(gè)需求是查找用戶附近的商鋪(包含關(guān)鍵字)商鋪的數(shù)據(jù)有130多萬(wàn),全放存放在MySQL中,發(fā)現(xiàn)用MySQL
LIKE“wsOehh%”這種方式檢索geohash值性能瓶頸很大,檢索130萬(wàn)行的數(shù)據(jù),平均花費(fèi)了8秒,這種響應(yīng)速度在生產(chǎn)環(huán)境中是無法忍受的。后來經(jīng)過不斷優(yōu)化,確定了CoreSeek+Redis+MvSQL的解決方案,一下子就把響應(yīng)速度減少到可接受的程度,這個(gè)方案的如下
·用每個(gè)商鋪的坐標(biāo)值轉(zhuǎn)換為geohash,用geohash作為Key,商鋪的id作為Value.存儲(chǔ)在Redis的set結(jié)合中。
·根據(jù)用戶的坐標(biāo)計(jì)算geohash,在Redis中用“keys*“的方法匹配查找用戶附近的商鋪geohash (geohash的特點(diǎn)是geohash編碼的前綴可
以表示個(gè)區(qū)域),獲得商鋪id。例如,用戶坐標(biāo)的geohash值是“wsOehh“,在Redis中使用“wsOehh*“搜索前緩為“wsOehh“的Key,
根據(jù)Key獲取Rset集合中保存的商鋪id。
·把商鋪id作為附加篩選條件,再加上主條件(例如商品的名稱關(guān)鍵字)在CoreSeek中繼續(xù)查找相應(yīng)的數(shù)據(jù)。
注意:這個(gè)方案的性能最終受限于Redis的讀取速度,由于Redis的“*”號(hào)操作是遍歷Redis中的所有Key,當(dāng)Redis中的Key到迭一定的規(guī)模后響應(yīng)速度會(huì)要慢,現(xiàn)在更推薦使用MongoDB來解決LBS問題。
3.MongoDB解決方案
MongoDB的一大亮點(diǎn)是封裝了大量的地理位置操作,全球流行的LBS服務(wù)“Foursquare”、國(guó)內(nèi)著名的打車App“快的”也曾經(jīng)使用MongoDB的地理位置查詢功能。
關(guān)于MougoDB處理LBS的原理和常用操作,請(qǐng)查閱本站前面“APP開發(fā)功能之LBS”。
使用MongoDB開發(fā)LBS服務(wù)有以下的優(yōu)點(diǎn)
·MongoDB自身的性能高,更新、查詢的速度快。
·通過副本集、分片等方法,很容易實(shí)DhlMongoDB的分布式部署,解決性能瓶頸。
. MongoDB己在App后臺(tái)中廣泛使用,很多開發(fā)者對(duì)開發(fā)部署MongoDB比較熟悉,減少運(yùn)維成本。MongoDB可支持下面的地理位置查找。
·查詢多邊形范圍的坐標(biāo)。
·查詢附近的坐標(biāo)。
·查詢圓形區(qū)域內(nèi)的坐標(biāo)。
好了,APP開發(fā)公司本文關(guān)于超找附近的人的項(xiàng)目開發(fā)經(jīng)驗(yàn)就分享到這里,希望能給您的工作帶來幫助,如果您有其他方面的疑問,可以聯(lián)系我們?cè)诰€客服,謝謝關(guān)注,博納網(wǎng)絡(luò)便自己整理。