对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。
Docs 菜单

地理空间查询

在本指南中,您可以学习;了解如何使用Scala驾驶员查询地理空间数据。您还可以学习;了解MongoDB支持的不同地理空间数据格式。

地理空间数据表示地球表面的位置。地理空间数据的示例包括:

  • 电影院位置

  • 国家/地区边界

  • 自行车骑行路线

  • 纽约市的狗狗运动区

theaterssample_mflix本指南中的示例使用Atlas示例数据集的 数据库中的 集合。要从Scala应用程序访问权限此集合,请创建一个连接到Atlas 集群的MongoClient,并将以下值分配给 databasecollection 变量:

val database: MongoDatabase = mongoClient.getDatabase("sample_mflix")
val collection: MongoCollection[Document] = database.getCollection("theaters")

要学习如何创建免费的MongoDB Atlas 集群并加载示例数据集,请参阅MongoDB 入门指南

要在 MongoDB 中存储和查询地理空间数据,请使用GeoJSON 。 GeoJSON 是由互联网工程任务组 (IETF) 创建的一种数据格式。

以下是 GeoJSON 中 MongoDB 总部的位置:

"location" : {
"type": "Point",
"coordinates": [-73.986805, 40.7620853]
}

有关 GeoJSON 的确切信息,请参阅 IETF 官方规范。

位置表示地球上的单个地点,并以包含两个或三个数值的大量形式给出:

  • 第一个位置的经度(必需)

  • 第二个位置的纬度(必需)

  • 第三个位置的海拔高度(选填)

重要

经度然后纬度

GeoJSON 将坐标排序为经度在前,纬度在后。 这可能令人惊讶,因为地理坐标系惯例通常首先列出纬度,然后列出经度。 请务必检查您正在使用的其他工具所使用的格式。 OpenStreetMap 和 Google Maps 等流行工具以纬度在前、经度在后的方式列出坐标。

GeoJSON 对象的类型决定了其几何形状。 几何形状由多个位置组成。

下面是一些常见的 GeoJSON 类型以及如何使用位置指定这些类型:

要学习;了解有关可在MongoDB中使用的形状的更多信息,请参阅服务器手册中的GeoJSON

要创建2dsphere索引,请使用Indexes.geo2dsphere()辅助程序为2dsphere索引创建规范。 将规范传递给MongoCollection.createIndex()方法以创建索引。

以下示例在theaters集合中的"location.geo"字段上创建2dsphere索引:

val indexObservable = collection.createIndex(Indexes.geo2dsphere("location.geo"))
Await.result(indexObservable.toFuture(), Duration(10, TimeUnit.SECONDS))

要学习;了解有关Scala驾驶员中索引的更多信息,请参阅“使用索引优化查询”指南。

您可以使用二维欧几里得平面上的xy 坐标来存储地理空间数据。二维平面上的坐标称为传统坐标对。

legacy coordinate pairs 具有以下结构:

{ "location" : [ x, y ] }

该字段值包含一个由两个值组成的大量,其中第一个值表示 x 轴值,第二个值表示 y 轴值。

要查询存储为传统坐标对的数据,必须将包含传统坐标对的字段添加到 2d索引。以下代码段使用 Indexes对象在 coordinates字段上创建 2d索引:

val indexObservable = collection.createIndex(Indexes.geo2d("coordinates"))
Await.result(indexObservable.toFuture(), Duration(10, TimeUnit.SECONDS))

要学习;了解有关Scala驾驶员中索引的更多信息,请参阅“使用索引优化查询”指南。

有关传统坐标对对的更多信息,请参阅服务器手册中地理空间查询指南的传统坐标对部分。

提示

支持的操作符

球面 (2dsphere) 和平面 (2d) 索引支持部分(但不是全部)相同的查询运算符。要查看操作符及其索引兼容性的完整列表,请参阅服务器手册中地理空间查询指南的地理空间查询操作符部分。

地理空间查询由查询操作符和作为查询参数的 GeoJSON 形状组成。

要查询地理空间数据,请使用以下查询运算符之一:

  • $near

  • $geoWithin

  • $nearSphere

  • $geoIntersects 需要 2dsphere 索引

您可以使用 Filters对象的 near()geoWithin()nearSphere()geoIntersects() 方法在Scala驾驶员中指定这些查询运算符。

要学习;了解有关地理空间查询运算符的更多信息,请参阅服务器手册中地理空间查询指南的地理空间查询运算符部分。

要查看 Filters 辅助方法的完整列表,请参阅 筛选器 API文档。

要指定在地理空间查询中使用的形状,请使用Scala驾驶员中的 PositionPointLineStringPolygon 类。

要学习;了解有关GeoJSON形状类的更多信息,请参阅GeoJSON包API文档。

以下示例使用 示例数据库中的MongoDB Atlastheaters sample_mflix集合。您可以在Scala驱动程序入门指南中学习;了解如何设立自己的免费套餐Atlas 集群以及如何加载示例数据集。

本节中的示例需要以下导入:

import org.mongodb.scala.*
import org.mongodb.scala.model.Indexes
import org.mongodb.scala.model.Filters
import org.mongodb.scala.model.Projections
import com.mongodb.client.model.geojson.{Point, Polygon, Position}
import java.util.Arrays
import java.util.concurrent.TimeUnit
import scala.concurrent.Await
import scala.concurrent.duration.Duration

theaterscollection已包含location.geo字段上的2dsphere索引。

要按从最近到最远的点搜索并返回文档,请使用 Filters对象的 near() 方法。 near() 方法使用 $near查询运算符构造查询。

以下示例返回距离指定GeoJSON Point实例不超过 1000 米的文档,并从最近到最远排序:

val refPoint = new Point(new Position(-73.986805, 40.7620853))
val findObservable = collection.find(Filters.near("location.geo", refPoint, Some(1000.0), Some(0.0)))
val results = Await.result(findObservable.toFuture(), Duration(10, TimeUnit.SECONDS))
{"_id": {"$oid": "59a47287cfa9a3a73e51e8e2"}, "theaterId": 1908, "location":
{"address": {"street1": "750 Seventh Ave", "city": "New York", "state": "NY",
"zipcode": "10019"}, "geo": {"type": "Point", "coordinates": [-73.983487, 40.76078]}}}
{"_id": {"$oid": "59a47286cfa9a3a73e51e838"}, "theaterId": 1448, "location":
{"address": {"street1": "1880 Broadway", "city": "New York", "state": "NY",
"zipcode": "10023"}, "geo": {"type": "Point", "coordinates": [-73.982094, 40.769882]}}}

提示

MongoDB 使用与 GPS 卫星相同的参考系来计算地球上空的几何形状。

要学习;了解有关 $near操作符的更多信息,请参阅服务器手册中的 $near 参考资料。

要搜索指定形状内的地理空间数据,请使用 Filters对象的 geoWithin() 方法。 geoWithin() 方法使用 $geoWithin查询运算符构造查询。

以下示例搜索长岛某个地区的电影院。该示例应用投影,以便每个结果仅包含 location.address.city字段,不包括 _id字段:

val longIslandTriangle = new Polygon(Arrays.asList(
new Position(-72.0, 40.0),
new Position(-74.0, 41.0),
new Position(-72.0, 39.0),
new Position(-72.0, 40.0)
))
val projection = Projections.fields(
Projections.include("location.address.city"),
Projections.excludeId()
)
val geoWithinComparison = Filters.geoWithin("location.geo", longIslandTriangle)
val findObservable = collection.find(geoWithinComparison).projection(projection)
val results = Await.result(findObservable.toFuture(), Duration(10, TimeUnit.SECONDS))
results.foreach(doc => println(doc.toJson()))
{"location": {"address": {"city": "Baldwin"}}}
{"location": {"address": {"city": "Levittown"}}}
{"location": {"address": {"city": "Westbury"}}}
{"location": {"address": {"city": "Mount Vernon"}}}
{"location": {"address": {"city": "Massapequa"}}}

下图显示了由 longIslandTriangle 变量定义的多边形以及表示查询返回的电影院位置的点。

长岛可搜索电影院的区域

要学习;了解有关 $geoWithin操作符的更多信息,请参阅服务器手册中的 $geoWithin 参考资料。

要学习;了解有关执行地理空间查询的更多信息,请参阅服务器手册中的地理空间查询