地理空间查询

在本页面:

地理空间数据

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

GeoJSON对象

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

要指定GeoJSON数据,请使用嵌入的文档:

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

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

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

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

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

<field>: { type: <GeoJSON type> , coordinates: <coordinates> }

例如,要指定GeoJSON Point::

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

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

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

旧版坐标对

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

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

通过数组指定(首选):

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

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

<field>: [<longitude>, <latitude> ]
  • 有效的经度值在[-180 180]

  • 有效的纬度值在[-90 90]

通过嵌入式文档指定:

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

如果指定纬度和经度坐标,第一个字段必须包含经度值,而第二个字段必须包含纬度值;即。

<field>: { <field1>: <longitude>, <field2>: <latitude> }
  • 有效的经度值在[-180 180]

  • 有效的纬度值在[-90 90]

为了指定旧版坐标对,数组比嵌入式文档更可取,因为某些语言不能保证关联地图的排序。

地理空间索引

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

2dsphere

索引支持查询,该查询可在类似地球的球体上计算几何形状。

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

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

其中<location field>是其值为GeoJSON对象或旧版坐标对的字段。

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

2d

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

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

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

其中<location field>是一个值为旧版坐标对的字段。

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

地理空间索引和分片集合

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

分片集合支持以下地理空间操作:

从MongoDB 4.0开始,分片集合支持$near$nearSphere查询。

在早期的MongoDB版本中,分片集合不支持$near$nearSphere 查询。相反,对于分片群集,必须使用$geoNear聚合阶段或geoNear命令(在MongoDB 4.0及更低版本中可用)。

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

涵盖查询

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

地理空间查询

[success] Note

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

2d索引用于球形查询可能会导致错误的结果,例如将2d索引用于环绕两极的球形查询。

地理空间查询操作符

MongoDB提供以下地理空间查询操作符:

名字

说明

$geoIntersects

选择与GeoJSON几何形状相交的几何形状。 2dsphere索引支持$geoIntersects.

$geoWithin

选择边界GeoJSON几何图形内的几何图形。2dsphere和2d索引支持$geoWithin.

$near

返回球体上某个点附近的地理空间对象。 需要地理空间索引。 2dsphere2d索引支持$near.

$nearSphere

返回接近球体上某一点的地理空间对象。需要地理空间索引。2dsphere2d索引支持$nearSphere.

有关更多细节(包括示例),请参见个别参考页面。

地理空间聚集阶段

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

步骤

说明

$geoNear

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

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

地理空间模型

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

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

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

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

操作方式

球面/平面查询

笔记

$near (GeoJSON centroid point in this line and the following line, 2dsphere index)

球形

另请参见 $nearSphere 运算符,该运算符与GeoJSON和2dsphere索引一起使用时提供相同的功能。

$near (legacy coordinates, 2d index)

平面

$nearSphere (GeoJSON point, 2dsphere index)

球形

提供与使用GeoJSON点和2dsphere索引的$ near操作相同的功能。对于球形查询,最好使用$ nearSphere而不是$ near运算符,后者在名称中显式指定球形查询。

$nearSphere (legacy coordinates, 2d index)

球形

请改用GeoJSON 点。

$geoWithin : { $geometry: … }

球形

$geoWithin : { $box: … }

平面

$geoWithin : { $polygon: … }

平面

$geoWithin : { $center: … }

平面

$geoWithin : { $centerSphere: … }

球形

$geoIntersects

球形

$geoNear aggregation stage (2dsphere index)

球形

$geoNear aggregation stage (2d index)

平面

例子

用以下文档创建一个集合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"
}
}
])

译者:杨帅

校对:杨帅