Geospatial Queries

在本页面

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

Geospatial Data

在 MongoDB 中,您可以将地理空间数据存储为GeoJSON对象或传统坐标对

GeoJSON Objects

要计算类地球球的几何形状,请将位置数据存储为GeoJSON objects

要指定 GeoJSON 数据,请使用具有以下内容的嵌入式文档:

  • 名为type的字段,用于指定GeoJSON 对象类型

  • 一个名为coordinates的字段,用于指定对象的坐标。

如果指定纬度和经度坐标,请先列出 经度 ,然后列出 latitude

  • 有效的经度值在-180180之间(包括两端值)。

    • 有效的纬度值在-9090之间(包括两端值)。
<field>: { type: <GeoJSON type> , coordinates: <coordinates> }

例如,要指定GeoJSON Point

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

有关 MongoDB 支持的 GeoJSON 对象的列表以及示例,请参见GeoJSON objects

对 GeoJSON 对象的 MongoDB 地理空间查询是在球体上计算的; MongoDB 使用WGS84参考系统对 GeoJSON 对象进行地理空间查询。

旧版坐标对

要计算欧几里得平面上的距离,请将您的位置数据存储为旧版坐标对,并使用2d索引。通过将数据转换为 GeoJSON Point 类型,MongoDB 支持通过2dsphere索引对旧坐标对进行球面计算。

要将数据指定为旧式坐标对,可以使用数组(* preferred *)或嵌入式文档。

  • 通过数组指定(* Preferred *):

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


 

If specifying latitude and longitude coordinates, list the  **longitude**  first and then  **latitude** ; i\.e\.

 

```javascript
<field>: [<longitude>, <latitude> ]
  • 有效的经度值在-180180之间(包括两端值)。

  • 有效的纬度值在-9090之间(包括两端值)。

  • 通过嵌入式文档指定:

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


 

If specifying latitude and longitude coordinates, the first field, regardless of the field name, must contains the  **longitude**  value and the second field, the  **latitude**  value ; i\.e\.

 

```javascript
<field>: { <field1>: <longitude>, <field2>: <latitude> }
  • 有效的经度值在-180180之间(包括两端值)。

  • 有效的纬度值在-9090之间(包括两端值)。

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

Geospatial Indexes

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

2dsphere

2dsphere索引支持计算地球上的几何的查询。

要创建2dsphere索引,请使用db.collection.createIndex()方法并指定字符串 Literals"2dsphere"作为索引类型:

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

其中<location field>是值为GeoJSON object传统坐标对的字段。

有关2dsphere索引的更多信息,请参见2dsphere Indexes

2d

2d索引支持计算二维平面上的几何的查询。尽管索引可以支持在球上进行计算的$nearSphere查询,但如果可能,请对球形查询使用2dsphere索引。

要创建2d索引,请使用db.collection.createIndex()方法,将 location 字段指定为键,并将字符串 Literals"2d"指定为索引类型:

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

其中<location field>是值为传统坐标对的字段。

有关2d索引的更多信息,请参见2d Indexes

地理空间索引和分片集合

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

对于分片集合,不支持使用$near$nearSphere进行查询。您可以改用geoNear命令或$geoNear聚合阶段。

您也可以使用$geoWithin$geoIntersect查询分片群集的地理空间数据。

Covered Queries

Geospatial indexes不能覆盖查询

Geospatial Queries

Note

对于球形查询,请使用2dsphere索引结果。

对于球形查询使用2d索引可能会导致错误的结果,例如对于围绕极点的球形查询使用2d索引。

地理空间查询运算符

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

NameDescription
$geoIntersects选择与GeoJSON几何相交的几何。 2dsphere索引支持$geoIntersects
$geoWithin在边界GeoJSON geometry内选择几何。 2dsphere2d索引支持$geoWithin
$near返回点附近的地理空间对象。需要地理空间索引。 2dsphere2d索引支持$near
$nearSphere返回球体上某个点附近的地理空间对象。需要地理空间索引。 2dsphere2d索引支持$nearSphere

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

Geospatial Command

MongoDB 提供以下地理空间命令:

CommandDescription
geoNear执行地理空间查询,该查询返回最接近给定点的文档。

geoNear需要geospatial index

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

地理空间聚集阶段

MongoDB 提供以下地理空间聚合管道阶段

StageDescription
$geoNear根据与地理空间点的接近程度返回有序的文档流。结合了$match$sort$limit的地理空间数据功能。输出文档包括附加距离字段,并且可以包括位置标识符字段。

$geoNear需要geospatial index

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

Geospatial Models

MongoDB 地理空间查询可以解释平面或球体上的几何。

2dsphere索引仅支持球形查询(即解释球形表面上的几何形状的查询)。

2d索引支持平面查询(即解释平面上的几何形状的查询)和某些球形查询。尽管2d索引支持某些球形查询,但对于这些球形查询使用2d索引可能会导致错误。如果可能,对球形查询使用2dsphere索引。

下表列出了每个地理空间操作所使用的地理空间查询运算符,受支持的查询:

OperationSpherical/Flat QueryNotes
$near(此行和下一行的GeoJSON重心点,2dsphere索引)Spherical另请参见$nearSphere运算符,与GeoJSON2dsphere索引一起使用时,该运算符提供相同的功能。
$near(legacy coordinates2d索引)Flat
$nearSphere(GeoJSON点,2dsphere索引)Spherical提供与使用GeoJSON点和2dsphere索引的$near操作相同的功能。


对于球形查询,最好使用$nearSphere而不是$near运算符,该$nearSphere以名称显式指定球形查询。
| $nearSphere(legacy coordinates2d索引)|球形|改用GeoJSON点。
| $geoWithin:\ { $geometry:… } |球形| |
| $geoWithin:\ { $box:… } |平面| |
| $geoWithin:\ { $polygon:… } |平面| |
| $geoWithin:\ { $center:… } |平面| |
| $geoWithin:\ { $centerSphere:… } |球形| |
|$geoIntersects|Spherical| |
| geoNear(2dsphere索引)|球形| |
| geoNear(2d索引)|平面| |
| $geoNear(2dsphere索引)|球形| |
| $geoNear(2d索引)|平面| |

Example

创建包含以下文档的集合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 米的文档,并按从最近到最远的 Sequences 排序:

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

以下操作使用geoNear命令返回与查询过滤器{ category: "Parks" }匹配的文档,该文档按距指定 GeoJSON 点最近到最远的 Sequences 排序:

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