Docs 菜单
Docs 主页
/
MongoDB Manual
/

地理空间查询

在此页面上

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

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

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

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

  • MongoDB Enterprise:基于订阅、自我管理的 MongoDB 版本

  • MongoDB Community:源代码可用、免费使用且可自行管理的 MongoDB 版本

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

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

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

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

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

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

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

重要

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

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

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

例如,要指定 GeoJSON 点

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

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

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

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

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

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

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

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

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

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

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

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

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

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

MongoDB 提供以下地理空间索引类型来支持地理空间查询。有关地理空间索引的更多信息,请参阅地理空间索引

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

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

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

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

注意

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

MongoServerError: Index build failed

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

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

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

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

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

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

注意

使用 2d 索引查询球形数据可能会返回不正确的结果或错误。例如,2d 索引不支持环绕极点的球形查询。

MongoDB 提供以下地理空间查询操作符:更多详情(包括示例),请参阅各个参考页。

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

注意

时间序列集合仅支持 $geoNear 聚合阶段,用于对来自2 dsphere 索引查询的地理空间数据进行排序。不能在时间序列集合中使用 $near$nearSphere 操作符

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

阶段
说明

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

$geoNear 需要地理空间索引。

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

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

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

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

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

操作
球形/平面查询
注意
$near(此行和下一行中的 GeoJSON 质心点,2dsphere 索引)
球形
另请参阅 $nearSphere 操作符,该操作符在与 GeoJSON2dsphere 索引结合使用时可提供相同的功能。
$near旧版坐标2 维索引)
平面
$nearSphereGeoJSON 点,2dsphere 索引)
球形

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

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

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

您可以使用 MongoDB Atlas 用户界面在 Atlas 中执行地理空间查询。

1

如果您的地理空间集合还没有地理空间索引,则必须创建一个。

  1. 为该集合选择数据库。

    主面板和左侧的 Namespaces 列出数据库中的集合。

  2. 选择集合。

    在左侧或主面板中选择包含地理空间数据的集合。主面板显示 FindIndexesAggregation 视图。

  3. 选择“索引”视图。

    打开 Index 视图后,Atlas 会显示集合中存在的所有索引。

  4. 定义地理类型的索引

    Create Index 按钮。

    定义地理类型索引。请参阅如何为 GeoJSON 对象构建索引

2
  1. 选择“查找”视图。

    从包含地理空间数据的集合中,选择 Find 标签页以查看地理空间集合。

  2. 输入查询。

    Filter文本框中输入查询。使用任意地理空间查询操作符对地理空间数据执行相关查询。地理空间查询可能类似于以下内容:

    {
    "coordinates": {
    $geoWithin: {
    $geometry: {
    type: "Polygon",
    coordinates: [
    [
    [-80.0, 10.00], [ -80.0, 9.00], [ -79.0, 9.0], [ -79.0, 10.00 ], [ -80.0, 10.0 ]
    ]
    ]
    }
    }
    }
    }
  3. 按“应用”按钮。

    Apply 按钮应用您的查询。Atlas 会过滤地理空间数据,以仅显示与您的地理空间查询相匹配的文档。

您可以在 MongoDB Atlas UI 中创建和执行聚合管道,以进行地理空间查询。

1
  1. 为该集合选择数据库。

    主面板和左侧的 Namespaces 列出数据库中的集合。

  2. 选择集合。

    在左侧或主面板中选择包含地理空间数据的集合。主面板显示 FindIndexesAggregation 视图。

  3. 选择 Aggregation(聚合)视图。

    当您首次打开Aggregation视图时,Atlas 会显示一个空的聚合管道。

2
  1. 选择聚合阶段。

    从左下角面板的 Select(选择)下拉菜单中选择聚合阶段。

    下拉列表右侧的切换指示是否已启用该阶段。

    使用 $geoNear 阶段在聚合管道中执行地理空间查询。

  2. 填充聚合阶段。

    用适当的值填充您的阶段。如果启用了评论模式,则管道构建器会为所选阶段提供语法指南。

    修改阶段时,Atlas 会根据当前阶段的结果更新右侧的预览文档。

    您的 $geoNear 阶段可能类似于:

    {
    near: { type: "Point", coordinates: [ -73.9667, 40.78 ] },
    spherical: true,
    query: { category: "Parks" },
    distanceField: "calcDistance"
    }
  3. 根据需要运行其他管道阶段。

    根据需要添加阶段以完善聚合管道。您可以添加 $out$merge 以将结果写入视图或当前集合。

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

后退

文本搜索(Text Search)