地理空间查询


进入MongoDB中文手册(4.2版本)目录

MongoDB支持对地理空间数据的查询操作。本章节介绍MongoDB的地理空间特性。

1 地理空间数据

MongoDB中,您可以将地理空间数据存储为GeoJSON对象或传统坐标对( legacy coordinate pairs)。

1.1 GeoJSON对象

要在类似地球的球体上计算几何形状,请将位置数据存储为GeoJSON对象。
要指定GeoJSON数据,请使用具有以下内容的嵌入式文档:

  • 一个GeoJSON对象类型的命名为type的字段;
  • 以及一个指定对象坐标的coordinates字段。
    如果指定纬度和经度坐标,请先列出经度(longitude ),然后再列出纬度(纬度)
    • 有效的经度值介于-180和之间180,并且包括-180和180;
    • 有效的纬度值介于-90和之间90,并且包括-90和90。
<field>: { type: <GeoJSON type> , coordinates: <coordinates> }

例如,要指定一个GeoJSON坐标点(GeoJSON Point)

location: {
      type: "Point",
      coordinates: [-73.856077, 40.848447]
}

有关MongoDB支持的GeoJSON对象的列表以及示例,请参阅GeoJSON对象
对GeoJSON对象的MongoDB地理空间查询是在球体上计算的;MongoDB使用WGS84参考系统对GeoJSON对象进行地理空间查询。

1.2 传统坐标对(Legacy Coordinate Pairs)

要计算欧几里得平面(Euclidean plane)上的距离,请将您的位置数据存储为传统坐标对并使用2d索引。通过将数据转换为GeoJSON Point类型,MongoDB支持通过2dsphere索引对传统坐标对进行球面计算。
要将数据指定为传统坐标对,可以使用数组(首选)或嵌入式文档。

通过数组指定(首选):

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

如果指定纬度和经度坐标,请先列出经度,然后再列出维度;即

<field>: [<longitude>, <latitude> ]
  • 有效的经度值介于-180和之间180,并且包括-180和180;
  • 有效的纬度值介于-90和之间90,并且包括-90和90。

通过嵌入式文档指定:

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

如果指定纬度和经度坐标,则第一个字段(无论字段名称如何)都必须包含经度值,第二个字段必须包含纬度值;即

<field>: { <field1>: <longitude>, <field2>: <latitude> }
  • 有效的经度值介于-180和之间180,并且包括-180和180;
  • 有效的纬度值介于-90和之间90,并且包括-90和90。

对于指定传统坐标对,数组优先于嵌入式文档,因为某些语言不保证关联地图的排序。

2 地理空间索引

MongoDB提供以下地理空间索引类型来支持地理空间查询。

2.1 2dsphere

2dsphere索引支持查询,该查询可计算类似地球的球体上的几何形状
要创建2dsphere索引,请使用 db.collection.createIndex()方法并指定字符串"2dsphere"作为索引类型:

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

其中,是一个字段,其值可以是 GeoJSON对象或传统坐标对。
有关2dsphere索引的更多信息,请参见2dsphere索引

2.2 2d

2d索引支持的查询,可计算二维平面的几何 。尽管索引可以支持$nearSphere的查询是在球体上进行计算,但如果可能,请对球面查询使用2dsphere索引。
要创建2d索引,请使用db.collection.createIndex() 方法,将位置字段指定为键,并将字符串"2d"指定为索引类型:

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

其中,是一个字段,其值为传统坐标对。
有关2d索引的更多信息,请参见2d索引

2.3 地理空间索引和分片集合

分片集合时,不能将地理空间索引用作分片键。但是,可以通过使用其他字段作为分片键在分片集合上创建地理空间索引。
分片集合支持以下地理空间操作:

  • $geoNear 聚合阶段;
  • $near和$nearSphere查询运算符(从MongoDB 4.0开始。

开始在MongoDB中4.0,$near和$nearSphere查询都支持分片集合。
在早期版本的MongoDB,$near和$nearSphere查询不支持分片的集合; 相反,对于分片群集,必须使用$geoNear聚合阶段或geoNear命令(在MongoDB 4.0及更低版本中可用)。
您还可以使用$geoWithin和$geoIntersect查询分片群集的地理空间数据 。

2.4 覆盖查询(Covered Queries)

地理空间索引不能覆盖查询

3 地理空间查询

注意
对于球形查询,请使用2dsphere索引结果。
将2d索引用于球形查询可能会产生错误的结果,例如将2d索引用于环绕两极的球形查询。

3.1 地理空间查询运算符

MongoDB提供以下地理空间查询运算符:

名称描述
$geoIntersects选择与GeoJSON几何形状相交的几何形状。2dsphere索引支持$geoIntersects。
$geoWithin选择边界GeoJSON几何内的几何。2dsphere和2D索引支持$geoWithin。
$near返回点附近的地理空间对象。需要地理空间索引。2dsphere和2D索引支持$near。
$nearSphere返回球体上某个点附近的地理空间对象。需要地理空间索引。2dsphere和2D索引支持 $nearSphere。

有关更多详细信息(包括示例),请参见各个参考页。

3.2 地理空间聚合阶段

阶段描述
$geoNear根据与地理空间点的接近程度返回有序的文档流。包含用于地理空间数据的$match$sort$limitd的功能。输出文档包括一个附加距离字段,并且可以包括位置唯一标识的字段。

$geoNear需要地理空间索引。

有关更多详细信息(包括示例),请参见$geoNear 参考页。

4 地理空间模型

MongoDB地理空间查询可以解释平面或球体上的几何。
2dsphere 索引仅支持球形查询(即解释球形表面几何形状的查询)。
2d索引支持平面查询(即解释平面上的几何形状的查询)和一些球形查询。虽然2d 索引支持某些球形查询,但2d对这些球形查询使用索引可能会导致错误。如果可能,将 2dsphere索引用于球形查询。
下表列出了每个地理空间操作所使用和支持的地理空间查询运算符:

操作球面(Spherical)查询/平面(Flat)查询备注
$near(此行和下一行的GeoJSON中心心点,2dsphere索引)球形另请参阅$nearSphere运算符,该运算符与GeoJSON和2dsphere索引一起使用时提供相同的功能。
$near(传统坐标,2d索引)平面
$nearSphere(GeoJSON点,2dsphere索引)球形提供与使用GeoJSON点和 2dsphere索引的$near操作相同的功能。

对于球形查询,最好使用 $nearSphere而不是$near, $nearSphere运算符显式指定球形查询的名称。
$nearSphere(传统坐标)球形请改用GeoJSON点。
$geoWithin:{ $geometry:…}球形
$geoWithin:{ $box:…}平面
$geoWithin:{ $polygon:…}平面
$geoWithin:{ $center:…}平面
$geoWithin:{ $centerSphere:…}球形
$geoIntersects球形
$geoNear聚合阶段(2dsphere索引)球形
$geoNear聚合阶段(2d索引)平面

5 示例

使用以下文档创建一个places集合:

db.places.insert( {
    name: "Central Park",
   location: { type: "Point", coordinates: [ -73.97, 40.77 ] },
   category: "Parks"
} );
db.places.insert( {
   name: "Sara D. Roosevelt Park",
   location: { type: "Point", coordinates: [ -73.9928, 40.7193 ] },
   category: "Parks"
} );
db.places.insert( {
   name: "Polo Grounds",
   location: { type: "Point", coordinates: [ -73.9375, 40.8303 ] },
   category: "Stadiums"
} );

以下操作在位置(location)字段上创建2dsphere索引 :

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

以下查询使用$near运算符返回距指定GeoJSON点至少1000米,最多5000米的文档,并按从最近到最远的顺序排序:

db.places.find(
   {
     location:
       { $near:
          {
            $geometry: { type: "Point",  coordinates: [ -73.9667, 40.78 ] },
            $minDistance: 1000,
            $maxDistance: 5000
          }
       }
   }
)

下操作使用geoNear聚合操作返回与查询过滤器{ category: “Parks” }匹配的文档,该文档按距指定GeoJSON点最近到最远的顺序排序:

db.places.aggregate( [
   {
      $geoNear: {
         near: { type: "Point", coordinates: [ -73.9667, 40.78 ] },
         spherical: true,
         query: { category: "Parks" },
         distanceField: "calcDistance"
      }
   }
] )


进入MongoDB中文手册(4.2版本)目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值