MongoDB地理位置功能总结

这篇博客总结了MongoDB的地理位置功能,包括术语解释、索引类型、常用方法和距离计算。强调了使用GeoJSON和2dsphere索引的重要性,并通过测试验证了$centerSphere算法的准确性。建议避免$geoNear在旧版分片集群中的使用,推荐使用最新版MongoDB并创建单一的2dsphere索引。
摘要由CSDN通过智能技术生成

MongoDB地理位置功能总结

1. 术语

术语 术语解释
Legacy Coordinates 笛卡尔坐标系,即平面坐标系。
GeoJSON GeoJSON是基于JavaScript 对象表示法的地理空间信息数据交换格式。GeoJSON对象可以表示几何、特征或者特征集合。GeoJSON支持下面几何类型:点、线、面、多点、多线、多面和几何集合。GeoJSON里的特征包含一个几何对象和其他属性,特征集合表示一系列特征。更多信息见 GeoJSON 。MongoDB中存储地理位置信息,建议采用GeoJSON格式存储。下文为该数据格式的示例。
距离单位 米(meter);平面单位(flat units):可以理解为经纬度的一度;弧度(radians):弧度乘以地球平均半径6359KM,近似表示地面距离

![image.png](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9jZG4ubmxhcmsuY29tL3l1cXVlLzAvMjAyMC9wbmcvMTczMjQyNS8xNTk4MDY2MjA4NjExLTBlNDFlMDE3LWU5NTAtNDE4YS1hZTM4LWYyMGUxMWFkOGIzYi5wbmc?x-oss-process=image/format,png#align=left&display=inline&height=498&margin=[object Object]&name=image.png&originHeight=586&originWidth=883&size=61453&status=done&style=shadow&width=750)

2. 索引类型

MongoDB支持两种索引:

索引类型 说明
2dsphere 球面索引,支持在类似地球的球体上计算几何图形的查询。
数据允许的情况下,均应改用该类索引。
2d 二维平面点的索引,用于计算平面距离。仅在存储的数据不能满足GeoJSON格式时,采用该索引。仅部分命令支持 2d 索引,只能在笛卡尔坐标对上创建。

创建命令如下

// 比如有places集合的数据如下
db.places.insert(
   {
   
      location : {
    type: "Point", coordinates: [ -73.97, 40.77 ] },
      name: "Central Park",
      category : "Parks"
   }
)
// 创建2dsphere索引
db.places.createIndex( {
   location : "2dsphere"} )
// 创建2d索引
db.places.createIndex( {
   "location.coordinates" : "2d"} )

另外地理位置索引支持与普通索引一起创建联合索引

// 组合索引:普通索引设置 1 正序, -1 倒序
db.places.createIndex( {
    location : "2dsphere" , category : -1, name: 1 } )
// 或者,2dsphere不一定在最前面
db.places.createIndex( {
     category : -1, location : "2dsphere" } )

3. 常用MongoDB地理位置方法

查询类型 几何类型 备注
$near(GeoJSON点,2dsphere索引) 球面 输入为GeoJSON时需要为2dsphere索引。结果已经排序,由近及远。MongoDB 4.0之前的版本不支持分片集群!!!
$near(传统坐标,2d索引) 平面 输入为普通坐标点时需要为2索引。结果已经排序,由近及远。MongoDB 4.0之前的版本不支持分片集群!!!
$nearSphere(GeoJSON点,2dsphere索引) 球面 结果已经排序,由近及远。MongoDB 4.0之前的版本不支持分片集群!!!
$nearSphere(传统坐标,2d索引) 球面 传统坐标会自动转化为GeoJSON点结果已经排序,由近及远。MongoDB 4.0之前的版本不支持分片集群!!!
$geoWithin:{$geometry:...} 球面
$geoWithin:{$box:...} 平面
$geoWithin:{$polygon:...} 平面
$geoWithin:{$center:...} 平面
$geoWithin:{$centerSphere:...} 球面
$geoIntersects 球面

4. 距离计算测试

  • 下面通过一个测试库验证下上面方法,测试collection的数据结构为
mongoimport restaurants.json -c restaurants
	imported 25359 documents
mongoimport restaurants.json -c restaurants2 
	imported 25359 documents
db.restaurants.findOne()

{
   
	"_id" : ObjectId("55cba2476c522cafdb05731e"),
	"location" : {
   
		"coordinates" : [
			-73.937699,
			40.8185813
		],
		"type" : "Point"
	},
	"name" : "Makkah Pizza Restaurant"
}
  • 创建索引
db.restaurants.createIndex({
    "location": "2dsphere" })
db.restaurants.createIndex({
    "location.coordinates": "2d" })

上面命令,分别创建了一个2dsphere索引和一个2d索引。

  • $near/$nearSphere 传入传统坐标点,使用2d索引

注意距离的单位是弧度,弧度乘以地球半径可以得到距离千米数,比如平面500米范围,其实是直径1公里的圆,转换为弧度为1.0/6359.0

// 查询500米范围内的餐馆
// $near
db.restaurants.find({
   "location.coordinates":{
    $near: [ -73.93769, 40.8185 ],$maxDistance: 1.0/6359.0} } ).count()
// 输出为1

// $nearSphere
db.restaurants.find({
   "location.coordinates":{
    $nearSphere: [ 
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值