相信如果提起地理数据的处理,首先想起的数据库就是postgis, 对大名鼎鼎的postgresql + 插件的方式来将POSTGRESQL 变成纯纯的地理数据处理的数据库,这是人尽皆知和童叟无欺的功能。
那么世界上如果我不想使用POSTGRESQL 的 postgis来处理我的地理数据以外的选择,那么NO.2 的选择就是mongodb的 GeoJSON 此时更简单的方式,以及不需要进行插件的方式,通过一整套MONGODB 提出的功能,你就可以拥有一个简单处理地理数据的 Professional database .
1 地理数据类型
2 MONGODB 如何存储地理数据
3 如何查询地理数据,与例子
4 地理数据的索引
1 首先我们需要代入如下一些地理的概念
point 点 , linestring 线 , polygon 多边形 , MultiPoint 多点 ,
MultiLineString , MultiPolygon , GeometryCollection 的在MONGODB 中的成型。
1 point 点
{type: "Point",coordinates:[90,2]} 经纬度
2 linestring 线
{type:"LineString",coordinates:[40,3],[45,3]}
3 polygon 多边形,多边形是通过多个点的描述通过线来终组成一个形状,特点是个点与后一个点一定是一样的,否则无法组成闭合的图形。
{type:"Polygon",coordinates:[
[0,0],[3,6],[6,1],[0,0]
]
}
polygons 多边形也分为 single Rings 和 Multiple Rings
上面其实就组成了我们形状中的,点线面,MONGODB 后面在对基本的数据进行进行组合
1 点组合
2 线组合
3 多边型组合
4 地理图形集合
以上就是mongodb 基于地理数据的基础 ,以及组合,其中数据主要分为三块
1 标注,标注地理的数据类型是什么如,point ,linestring , polygon ,MulitiPoint, MultiLineString, MultiPolygon, GeometryCollection
2 数据内容 ,corrdinates 通过数组的方式将一组描述 点,线,面(多边体),以及组合的数据进行合并。
总体来说地理数据是又简单到复杂,点,线,面(多边体),组合成多点, 多线,多面等类型。
2 MONGODB 如何存储和表达这些数据,这里存储地理数据的方式在MONGODB 中表现为 GEOJSON 数据。这个存储地理数据的JSON标准是由IETF 在2016年发布的RFC7946中规定的如何存储地理数据。
https://datatracker.ietf.org/wg/geojson/charter/
具体的信息可以查询上述网站,获得详细的信息。
https://docs.mongodb.com/manual/reference/geojson/
在mongodb中具体的展示GEOJSON 的格式为
标记location 在 location 中通过 coordinates 来存储定义个地理信息,如下面的位置点信息。
或者点比较多的多边形
此外一个document 中的location的信息应该集中存放,例如一个人的详细信息中包含他的家的地址 和 单位的地址,如下方的经纬度数据的存放
db.records.save( {
name : "John Smith",
addresses : [ {
context : "home" ,
location : [ 55.5, 42.3 ]
} ,
{
context : "work",
location : [ -74 , 44.74 ]
}
]
} )
3 地理位置查询主要有四种查询
1 $near
2 $geoWithin
3 $nearSphere
4 $geoIntersects
下面针对部分查询方式给出查询的样例
near 样例
下面有导入了一个地理数据的collection , 数据内容是简单的地名和所在的经纬度信息以及他属于的地区的门类。
特殊查询,我们查出在经纬度在 【-73.9667, 40.78
】的地方有哪些周围在1公里到5公里的其他被标注的地方有哪些.
下面的查询语句值直接从 restaurants collection 中查询经纬度在[ -73.9667, 40.78 ] 与这个点周围1 公里 到 5 公里中存在的其他的 restaurants 有哪些,并紧紧显示这些地名。
db.restaurants.find(
{
location:
{ $near:
{
$geometry: { type: "Point", coordinates: [ -73.9667, 40.78 ] },
$minDistance: 100,
$maxDistance: 500
}
}
}
,{name:1,_id:0}
)
2 仅仅查询小于与坐标点900米的距离,并且名字必须是,“”Members Dining Room @ The Met Museum"
db.restaurants.find(
{ location:
{ $near :
{$geometry :
{type:"point" ,coordinates: [ -73.9667, 40.78 ], $minDistance: 900 }
}
},name: "Members Dining Room @ The Met Museum"
}
)
2 geoWithin 样例, 这里通过geoWithin 来计算在经纬度半径范围内存在的餐馆的数量
db.restaurants.find(
{location: {
$geoWithin:{$center:[[-74.138492, 40.631136],0.01]}
}
}
).count()
通过上面的案例,我们在一些地理位置数据的筛选通过mongodb来操作是非常简单的。
其他样例可以查看下面的网站中的例子
https://dev.to/vcpablo/4-ways-to-find-geojson-data-in-mongodb-14pb
4 关于查询中MONGODB 使用的索引是地理位图索引
那么查询数据的时候,需要建立索引,空间索引,如果不进行建立则查询会出现这样的错误。
那么在你进行地理数据的查询中,需要注意的就是针对地理数据进行空间索引的建立。
关于mongodb 的 2d 索引默认的精度在60厘米,可硬通过调整精度降低索引的大小
db.restaurants.createIndex(
{ location: "2dsphere"},
{background:true,name:"idx_location"}
)
在地理数据存储和计算方面POSTGRESQL 的POSTGIS 是业界的 ,但在地理位图方面MONGODB 的地理数据的存储和计算也可以尝试,尤其在高并发的情况下,可能会给你一个 “惊艳” 的结果。