Docs 菜单

Docs 主页开发应用程序MongoDB Manual

地理空间查询

在此页面上

  • 兼容性
  • 地理空间数据
  • 地理空间索引
  • 地理空间查询
  • 地理空间模型
  • 在 Atlas 中执行地理空间查询
  • 举例

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

您可以对以下环境中托管的部署使用地理空间查询:

  • MongoDB Atlas :用于在云中部署 MongoDB 的完全托管服务

对于 MongoDB Atlas 中托管的部署,您可以在用户界面中使用查询 Filter栏或聚合构建器来运行地理空间查询。要了解更多信息,请参阅在 Atlas 中执行地理空间查询。

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

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

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

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

  • 名为 coordinates 的字段,指定对象的坐标。

    重要

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

    • 有效经度值介于 -180180 之间,两者均包括在内。

    • 有效纬度值介于 -9090 之间,两者均包括在内。

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

例如,要指定 GeoJSON 点

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

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

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

要计算欧几里得平面上的距离,请将位置数据存储为传统坐标对并使用 索引。如果您手动将数据转换为 GeoJSON2d2dsphere Point 类型 ,则 MongoDB 通过使用 索引支持传统坐标对上的球面计算。

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

通过数组指定(首选):
<field>: [ <x>, <y> ]

如果指定纬度和经度坐标,则先列出 longitude,然后列出 latitude;即

<field>: [<longitude>, <latitude> ]
  • 有效经度值介于 -180180 之间,两者均包括在内。

  • 有效纬度值介于 -9090 之间,两者均包括在内。

通过嵌入式文档指定:
<field>: { <field1>: <x>, <field2>: <y> }

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

<field>: { <field1>: <longitude>, <field2>: <latitude> }
  • 有效经度值介于 -180180 之间,两者均包括在内。

  • 有效纬度值介于 -9090 之间,两者均包括在内。

在指定传统坐标对时,数组要优于嵌入式文档,因为某些语言不能保证关联映射的顺序。

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

2 dsphere索引支持在类地球球体上计算几何图形的查询。

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

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

其中<location field>是一个字段,其值为GeoJSON 对象传统坐标对。

注意

如果尝试在包含 geoJSON 点数组的字段上创建索引,索引构建将失败并返回以下错误:

MongoServerError: Index build failed

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

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

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

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

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

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

对collection进行分片时,不能将地理空间索引用作分片。但是,您可以使用其他field作为分片键,在分片collection上创建地理空间索引。

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

从 MongoDB 4.0 开始,sharded collection支持$near$nearSphere查询。

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

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

地理空间索引无法涵盖查询。

注意

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

使用2d索引进行球面查询可能会导致不正确的结果,例如使用2d索引进行环绕极点的球面查询。

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

名称
说明
$geoIntersects
选择与 GeoJSON 几何图形相交的几何图形。2dsphere 索引支持 $geoIntersects
选择在边界 GeoJSON 几何图形内的几何图形。2dsphere2d 索引支持 $geoWithin
返回接近某个点的地理空间对象。需要地理空间索引。2dsphere2d 索引支持 $near
返回与球面上的某个点接近的地理空间对象。需要地理空间索引。2dsphere2d 索引支持 $nearSphere

更多详情(包括示例),请参阅单独的参考页。

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

阶段
说明

根据与地理空间点的接近程度返回有序的文档流。针对地理空间数据,整合了 $match$sort$limit 功能。输出文档包含一个额外的距离字段,并可包含一个位置标识符字段。

$geoNear需要地理空间索引。

更多详情(包括示例),请参阅 $geoNear 参考页。

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

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

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

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

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

提供与使用$near GeoJSON 点和2 dsphere 索引的 操作相同的功能。

对于球面查询,最好使用在名称中显式指定球面查询的 $nearSphere,而非 $near 运算符。

球形
使用 GeoJSON 点。
球形
$geoWithin : { $box: ... }
平面
$geoWithin : { $polygon: ... }
平面
$geoWithin : { $center: ... }
平面
球形
球形
$geoNear聚合阶段( 2 dsphere索引)
球形
$geoNear聚合阶段( 2 d索引)
平面

使用以下文档创建集合 places

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

下面的操作将在 location 字段上创建一个 2dsphere 索引:

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

上面的 places 集合有一个 2dsphere 索引。以下查询使用 $near 运算符返回距离指定 GeoJSON 点 1,000-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"
}
}
] )
← 文本搜索语言