前言

某些 APP 中會有類似 “搜尋附近景點” 的功能需求,需要在資料中搜尋位於某一座標點若干距離內的資料,將整個資料庫數據 dump 出並分別計算距離的方法並不實際且效率很差,此時我們便可以利用 MongoDB 內建的 地理位置索引 功能實現。

資料庫結構

我們的資料結構大致如圖

其中 loc 的結構為 [loc, lat]

搜尋方法

這邊我們使用 Python 作為示範教學,搜尋座標點附近 500 公尺 內的資料。 其中 db 已於 config.py 中先完成初始化,您亦可刪除程式碼中與 config 有關的內容並在函式執行前先行初始化 db

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import config # Self-created for initializing db. You can also ignore it and implement yours.
from bson.son import SON
from pymongo import GEOSPHERE
from typing import List


def search_nearby(
latitude: float, longitude: float, max_distance: int = 500
) -> List[dict]:
"""Search Nearby data

Args:
latitude (float): Latitude of the search location
longitude (float): Longitude of the search location
max_distance (int, optional): Search distance (measured in meter). Defaults to 500.

Returns:
List[dict]: Search result
"""
result = []
config.db["latest"].create_index([("loc", GEOSPHERE)])
query = {
"loc": {
"$near": SON(
[
(
"$geometry",
SON(
[
("type", "Point"),
("coordinates", [longitude, latitude]),
]
),
),
("$maxDistance", max_distance),
]
)
}
}
for each in config.db["latest"].find(query):
result.append(each)
return result

如此便能搜尋附近的資料。若要再更近一步限制搜尋結果,亦可使用如 limit 的方式限制搜尋筆數。

References