MongoDB
是一個基于分布式文件存儲的數(shù)據(jù)庫。由C++語言編寫。旨在為WEB應(yīng)用提供可擴展的高性能數(shù)據(jù)存儲解決方案。
前言
在移動開發(fā)中,經(jīng)常會用到定位的功能,例如美團、餓了么、貓眼電影等應(yīng)用,都使用了定位經(jīng)緯度,可以查詢用戶位置附近的一些服務(wù)、商家等信息。
本篇文章將會講述如何利用Mongodb進行數(shù)據(jù)存儲、定位查詢。
本方案為最佳實踐,實現(xiàn)功能如下:
- 帶經(jīng)緯度數(shù)據(jù)的存儲
- 根據(jù)用戶經(jīng)緯度,查詢由近到遠(yuǎn)的數(shù)據(jù)(分頁)
- 附帶距離數(shù)值(數(shù)據(jù)庫層級的計算)
- 可設(shè)置最大距離
一句話形容就是 : 存儲帶經(jīng)緯度的數(shù)據(jù),并且根據(jù)用戶的不同位置,返回可分組、帶距離的數(shù)據(jù)列表
注意,Mongodb版本在2.4以上
分析
舉個例子,我們需要做一個應(yīng)用,管理員可以把商家信息發(fā)布到應(yīng)用上,用戶打開應(yīng)用可以看到距離自己由近到遠(yuǎn)的商品,并且可以看到距離多少。
Mongodb有一種索引--地理空間索引,利用它可以進行經(jīng)緯度的計算,下面繼續(xù)介紹如何使用該功能。
實現(xiàn)
下面以Nodejs+mongoose為例
- 創(chuàng)建Schema:
const mongoose = require( 'mongoose' );
let VenuesSchema = new mongoose.Schema( {
name: String,
address: String,
location: {
type: [ Number ],
index: {
type: '2dsphere',
sparse: true
}
}
}, {
collection: 'Venues'
} )
- 創(chuàng)建Model
let VenuesModel = mongoose.model(‘Venues’, VenuesSchema)
- 插入數(shù)據(jù)
按照以下數(shù)據(jù)格式往數(shù)據(jù)庫插入數(shù)據(jù):
{
"name": "音樂派KTV(銀泰城)",
"address": "武侯區(qū)高新區(qū)天府四街益州大道口銀泰城4F"
"location" : [
104.05801,
30.5411
],
}
- 查看用戶附近的數(shù)據(jù)
let matchQuery = {
“name” : /音樂/ig
} // 額外篩選,此處查詢名字包含音樂的數(shù)據(jù)
let venuesCount = await VenuesModel.count().exec()
VenuesModel.aggregate( [
{
$geoNear: {
near: { type: 'Point', coordinates: [
104.05801 , //用戶經(jīng)度
30.5411 //用戶緯度
] },
distanceField: 'distance', // 距離數(shù)值字段名
spherical: true,
maxDistance: 1000 // (Int類型的最大距離--米,例如500,1000),
query: matchQuery,
limit: venuesCount
}
},
{
$match: matchQuery
},
{
$count: 'venuesCount'
}, //此處添加了此處,則返回數(shù)據(jù)量,如需返回具體數(shù)據(jù)列表,刪除此處
{
$skip: 30
}, // 分頁,跳過數(shù)據(jù)數(shù)量
{
$limit: 30
} // 分頁,返回的數(shù)據(jù)數(shù)量
] )
總結(jié)
本次主要分享位置索引和aggregate的用法,十分實用的一個功能。
- 返回的數(shù)據(jù)默認(rèn)就是近到遠(yuǎn)的數(shù)據(jù)
- 不要忘了數(shù)據(jù)庫字段location的索引配置
- 距離信息會附帶在返回的信息列表中,會有一個distance字段(我們定義的,可以修改)

圖片發(fā)自簡書App