簡介
隨著近幾年各類移動終端的迅速普及,基於地理位置的服務(LBS)和相關應用也越來越多,而支撐這些應 用的最基礎技術之一,就是基於地理位置資訊的處理。我所在的項目也正從事相關係統的開發,我們使用的是 Symfony2+Doctrine2 ODM+MongoDB的組合。
我們將這些技術要點整理成文,希望能夠通過本文的介紹和案例,詳細 解釋如何使用MongoDB進行地理位置資訊的查詢和處理。在文章的開頭,我們也會先介紹一下業界通常用來處理地理位置信 息的一些方案並進行比較,讓讀者逐步瞭解使用MongoDB查詢及處理地理位置資訊的優勢。
本文使用了Symfony2和 Doctrine2作為Web應用的開發架構,對於想瞭解Symfony2的資料庫操作的讀者來說閱讀本文也可以瞭解和掌握相關的技術和 使用方法。
1. LBS類應用特點
不管是什麼LBS應用,一個共同的特點就是:他們的資料都或多或少包含了地 理位置資訊。而如何對這些資訊進行查詢、處理、分析,也就成為了支撐LBS應用的最基礎也是最關鍵的技術問題。
而由於地理位置資訊的特殊性,在開發中經常會有比較難以處理的問題出現,比如:由於使用者所在位置的不固定性,使用者可 能會在很小範圍內移動,而此時經緯度值也會隨之變化;甚至在同一個位置,通過GPS裝置擷取到的位置資訊也可能不一樣 。所以如果通過經緯度去擷取周邊資訊時,就很難像傳統資料庫那樣做查詢並進行緩衝。
對於這個問題,有讀者可 能會說有別的處理方案,沒錯,比如只按經緯度固定的幾位小數點做索引,比如按矩陣將使用者劃分到某固定小範圍的地區( 可以參考後文將會提到的geohash)等方式,雖然可以繞個彎子解決,但或多或少操作起來比較麻煩,也會犧牲一些精度, 甚至無法做到效能的最佳化,所以不能算作是最佳的解決辦法。
而最近幾年,直接支援地理位置操作的資料庫層出 不窮,其操作友好、效能高的特性也開始被我們慢慢重視起來,其中的佼佼者當屬MongoDB。
MongoDB在地理位置信 息的處理上有什麼優勢?下面我們通過一個簡單的案例來對比一下各種技術方案之間進行進行地理位置資訊處理的差異。
2. 幾個地理位置資訊處理方案的對比和分析
1. 確定功能需求
對於任何LBS應用來說,讓使用者尋找周 圍的好友可能都是一個必不可少的功能,我們就以這個功能為例,來看看各種處理方案之間的差異和區別。
我們假 設有如下功能需求:
顯示我附近的人
由近到遠排序
顯示距離
2. 可能的技術方案
排除一些不通用和難以實現的技術,我們羅列出以下幾種方案:
基於MySQL資料庫
採用GeoHash索引,基於MySQL
MySQL空間儲存(MySQL Spatial Extensions)
使用MongoDB儲存地理位置資訊
我們一個個來分析這幾種方案。
方案1:基於MySQL資料庫
MySQL的使用非常簡單。對於大部分已經使用 MySQL的網站來說,使用這種方案沒有任何遷移和部署成本。
而在MySQL中查詢“最近的人”也僅需一條SQL即 可,
SELECT id, ( 6371 * acos( cos( radians(37) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(-122) ) + sin( radians(37) ) * sin( radians( lat ) ) ) ) AS distance FROM places HAVING distance < 25 ORDER BY distance LIMIT 0 , 100;
註:這條SQL查詢的是在lat,lng這 個座標附近的目標,並且按距離正序排列,SQL中的distance單位為公裡。
但使用SQL語句進行查詢的缺點也顯而易 見,每條SQL的計算量都會非常大,效能將會是嚴重的問題。
先別放棄,我們嘗試對這條SQL做一些最佳化。
可 以將圓形地區抽象為正方形,如下圖