On this page
Geospatial Queries
在本页面
MongoDB 支持对地理空间数据的查询操作。本节介绍 MongoDB 的地理空间功能。
Geospatial Data
在 MongoDB 中,您可以将地理空间数据存储为GeoJSON对象或传统坐标对。
GeoJSON Objects
要计算类地球球的几何形状,请将位置数据存储为GeoJSON objects。
要指定 GeoJSON 数据,请使用具有以下内容的嵌入式文档:
名为
type
的字段,用于指定GeoJSON 对象类型和一个名为
coordinates
的字段,用于指定对象的坐标。
如果指定纬度和经度坐标,请先列出 经度 ,然后列出 latitude :
有效的经度值在
-180
和180
之间(包括两端值)。- 有效的纬度值在
-90
和90
之间(包括两端值)。
- 有效的纬度值在
<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> ]
有效的经度值在
-180
和180
之间(包括两端值)。有效的纬度值在
-90
和90
之间(包括两端值)。通过嵌入式文档指定:
<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> }
有效的经度值在
-180
和180
之间(包括两端值)。有效的纬度值在
-90
和90
之间(包括两端值)。
为了指定旧式坐标对,数组优先于嵌入式文档,因为某些语言不保证关联 Map 的排序。
Geospatial Indexes
MongoDB 提供以下地理空间索引类型以支持地理空间查询。
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 Queries
Note
对于球形查询,请使用2dsphere
索引结果。
对于球形查询使用2d
索引可能会导致错误的结果,例如对于围绕极点的球形查询使用2d
索引。
地理空间查询运算符
MongoDB 提供以下地理空间查询运算符:
Name | Description |
---|---|
$geoIntersects | 选择与GeoJSON几何相交的几何。 2dsphere索引支持$geoIntersects。 |
$geoWithin | 在边界GeoJSON geometry内选择几何。 2dsphere和2d索引支持$geoWithin。 |
$near | 返回点附近的地理空间对象。需要地理空间索引。 2dsphere和2d索引支持$near。 |
$nearSphere | 返回球体上某个点附近的地理空间对象。需要地理空间索引。 2dsphere和2d索引支持$nearSphere。 |
有关更多详细信息(包括示例),请参见各个参考页。
Geospatial Command
MongoDB 提供以下地理空间命令:
Command | Description |
---|---|
geoNear | 执行地理空间查询,该查询返回最接近给定点的文档。 |
geoNear需要geospatial index。 |
有关更多详细信息(包括示例),请参阅geoNear参考页。
地理空间聚集阶段
MongoDB 提供以下地理空间聚合管道阶段:
Stage | Description |
---|---|
$geoNear | 根据与地理空间点的接近程度返回有序的文档流。结合了$match,$sort和$limit的地理空间数据功能。输出文档包括附加距离字段,并且可以包括位置标识符字段。 |
$geoNear需要geospatial index。 |
有关更多详细信息(包括示例),请参阅$geoNear参考页。
Geospatial Models
MongoDB 地理空间查询可以解释平面或球体上的几何。
2dsphere
索引仅支持球形查询(即解释球形表面上的几何形状的查询)。
2d
索引支持平面查询(即解释平面上的几何形状的查询)和某些球形查询。尽管2d
索引支持某些球形查询,但对于这些球形查询使用2d
索引可能会导致错误。如果可能,对球形查询使用2dsphere
索引。
下表列出了每个地理空间操作所使用的地理空间查询运算符,受支持的查询:
Operation | Spherical/Flat Query | Notes |
---|---|---|
$near(此行和下一行的GeoJSON重心点,2dsphere索引) | Spherical | 另请参见$nearSphere运算符,与GeoJSON和2dsphere索引一起使用时,该运算符提供相同的功能。 |
$near(legacy coordinates,2d索引) | Flat | |
$nearSphere(GeoJSON点,2dsphere索引) | Spherical | 提供与使用GeoJSON点和2dsphere索引的$near操作相同的功能。 |
对于球形查询,最好使用$nearSphere而不是$near运算符,该$nearSphere以名称显式指定球形查询。
| $nearSphere(legacy coordinates,2d索引)|球形|改用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" }
}
)