当前位置:   article > 正文

Mongodb地理信息数据查询

Mongodb地理信息数据查询

学习mongodb,体会mongodb的每一个使用细节,欢迎阅读威赞的文章。这是威赞发布的第78篇mongodb技术文章,欢迎浏览本专栏威赞发布的其他文章。如果您认为我的文章对您有帮助或者解决您的问题,欢迎在文章下面点个赞,或者关注威赞。谢谢。

通过阅读文档,了解Mongodb除了支持文档查询外,还支持地理信息坐标及临近查询。本文就对Mongodb对地理信息查询的支持进行介绍。

地理信息数据

在Mongodb数据库中,用户可以使用GeoJSON对象或者经纬坐标对的形式来保存地理信息数据。

GeoJSON对象

Mongodb使用GeoJSON对象保存数据以便于在地理空间中进行计算。用户使用嵌入文档的形式定义GeoJSON对象的数据,包括

  • 一个名为type的字段,定义了GeoJSON对象的类型
  • 一个名为coordinates的字段,指定了对象的坐标信息
<field>: { type: <GeoJSON type>, coordinates: <coordinates>}

如定义一个GeoJSON类型的点

  1. location: {
  2. type: "Point",
  3. coordinates: [-73.856077, 40.848447]
  4. }

当然,Mongodb也支持定义GeoJSON列表,具体可以参考本系列的其他文章。

Mongodb计算地理信息数据时,使用WGS84坐标系。

经纬坐标对

为了计算欧式距离,除了定义GeoJSON对象外,用户还可以将数据保存为经纬坐标对的形式,并建立一个平面二维索引。当用户将经纬坐标对转换成GeoJSON点类型的数据后,利用空间二维索引,Mongodb可以支持曲面空间数据计算。

用户可以使用数组或嵌入文档的形式,来保存坐标对数据。mongodb推荐用户使用数组的形式来保存数据。

<field>: [<x>, <y>]

或者使用经纬度坐标

<field>:[<经度坐标>, <纬度坐标>]

其中经度坐标范围在-180到180之间,包含-180和180. 而纬度坐标是-90到90之间,同样包含-90和90.

使用嵌入式文档的形式来定义坐标对

<field>: {<field1>: <x>, <field2>: <y>}

或者使用经纬度坐标来定义位置信息。

<field>: { <field1>: <longitude>, <field2>: <latitude>}

与使用数组定义一致,经度定义在-180到180之间,包含-180和180两个数值。纬度在-90到90之间,同样包含两个边界。

地理信息索引

为了提高地理信息查询的性能,mongodb允许用户添加地理信息索引来时间数据的快速查询和计算。

二维空间索引

二维空间索引,支持曲面地理信息计算

用户使用db.collection.createIndex建立二维空间索引. 其中<location field>可以是一个坐标对或者GeoJSON类型的对象。

db.collection.createIndex( {<location field>: "2dsphere"})

二维平面索引

二维平面支持在两个维度的平面地理信息查询。尽管二维平面索引支持使用$nearSphere的空间查询,但用户在进行空间地理信息查询时,尽量使用二维空间索引。

用户使用db.collection.createIndex()方法,来创建二维平面索引。

db.collection.createIndex({<location field>: "2d"})

其中,<location field>字段是坐标对。

地理信息查询

用户使用二维平面索引查询时,mongdb可能会返回错误的数据或者报错。例如二维平面索引不支持跨越极点的查询 。

地理信息查询操作符

mongodb提供了4个操作符 ,用于查询地理信息。

操作符

描述

$geoIntersects

查询相交的地理信息数据

$geoWithin

查询包含的地理信息数据

$near

查询临近的平面地理对象

$nearSphere

查询临近的空间地理对象

聚合管道中的地理信息操作符

mongodb同样提供了一个应用在聚合管道中的地理信息操作符

操作符

描述

$geoNear

查询临近指定点的空间数据文档, 与$match, $sort, $limit配合使用。输出文档包含了一个额外的距离字段。

地理信息模型

mongodb的地理信息查询可以在平面坐标系当中执行,也可以应用在空间查询当中。

使用二维空间索引时,只能进行空间当中的地理信息查询。而使用二维平面索引时,既可以进行平面空间查询,也可以进行部分空间查询。用户使用二维平面索引查询时,mongdb可能会返回错误的数据或者报错。下面的表格,列出了空间查询操作符所支持的查询空间类型和备注信息。

操作符

支持查询空间类型

$near(使用GeoJSON对象进行查询,集合中包含2d空间索引)

空间

$near(使用坐标对象进行查询,集合中包含2d平面索引)

平面

$nearSphere(GeoJSON点,二维空间索引)

空间

$nearSphere(坐标点,二维平面索引)

空间

$geoWithin: {$geometry:...}

空间

$geoWithin: {$box:...}

平面

$geoWithin: {$polygon:...}

平面

$geoWithin: {$center:...}

平面

$geoWithin: {$centerSphere:...}

空间

$geoIntersects

空间

聚合管道中的$geoNear, 带有二维空间索引

空间

聚合管道中的$geoNear, 带有二维平面索引

平面

应用

创建集合places并插入数据

  1. db.places.insertMany([
  2. {
  3. name: "Central Park",
  4. location: { type: "Point", coordinates: [-73.97, 40.77] },
  5. category: "Parks"
  6. },
  7. {
  8. name: "Sara D. Roosevelt Park",
  9. location: { type: "Point", coordinates: [-73.9928, 40.7193] },
  10. category: "Parks"
  11. },
  12. {
  13. name: "Polo Grounds",
  14. location: { type: "Point", coordinates: [-73.9375, 40.8308] },
  15. category: "Stadiums"
  16. }
  17. ]);

创建二维空间索引

db.places.createIndex({ location: "2dsphere" });

编写查询语句,要求查询出距离点{ type: "Point", coordinates: [-73.9667, 40.78]一公里到五公里范围内的兴趣点。

  1. db.places.find({
  2. location: {
  3. $near: {
  4. $geometry: { type: "Point", coordinates: [-73.9667, 40.78] },
  5. $minDistance: 1000,
  6. $maxDistance: 5000
  7. }
  8. }
  9. });

构建管道查询,查询出点{ type: "Point", coordinates: [ -73.9667, 40.78 ] }附近的公园信息

  1. db.places.aggregate([
  2. {
  3. $geoNear: {
  4. near: { type: "Point", coordinates: [-73.9667, 40.78] },
  5. distanceField: "calcDistance",
  6. query: { category: "Parks" },
  7. spherical: true
  8. }
  9. }
  10. ]);

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号