Docs 菜单
Docs 主页
/ / /
Java (Sync) 驱动程序
/ / /

按地理空间搜索

在此页面上

  • Overview
  • 地球坐标
  • GeoJSON 位置
  • GeoJSON 类型
  • 插入包含GeoJSON数据的文档
  • Index
  • 2D 平面上的坐标
  • 插入包含传统坐标的文档
  • Index
  • 地理空间查询
  • 查询运算符
  • 查询参数
  • 示例
  • 按距离查询
  • 在范围内查询

在本指南中,您可以了解如何使用 MongoDB Java 驱动程序搜索地理空间数据,以及 MongoDB 支持的不同地理空间数据格式。

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

  • 电影院位置

  • 国家/地区边界

  • 自行车骑行路线

  • 纽约市的狗狗运动区

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

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

"MongoDB Headquarters" : {
"type": "point",
"coordinates": [-73.986805, 40.7620853]
}

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

位置表示地球上的单个位置,在代码中作为包含两个或三个数值的数组存在:

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

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

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

重要

经度然后纬度

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

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

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

  • Point:单个位置。 这可以表示 雕塑 的位置。

  • LineString:由两个或多个位置组成的大量,从而形成一系列线段。 这可以代表 中国长城的路线。

  • Polygon:位置大量,其中第一个和最后一个位置相同,因此包含一些空格。 这可以代表 梵蒂冈城内的土地。

要进一步了解可在 MongoDB 中使用的形状,请参阅GeoJSON 手册条目。

要插入存储GeoJSON数据的文档,请创建一个包含GeoJSON值的文档并将该文档传递给insertOne()方法。

以下示例插入一个包含location.geo字段的文档,其中包含GeoJSON数据:

// Add your MongoCollection setup code here
Point point = new Point(new Position(-74.0065, 40.7085));
Document theater = new Document("theaterId", 1203)
.append("location", new Document("geo", point));
InsertOneResult result = collection.insertOne(theater);

要学习;了解有关插入文档的更多信息,请参阅插入操作指南。

要查询以 GeoJSON 格式存储的数据,请将包含 GeoJSON 数据的字段添加到2dsphere索引中。 以下代码片段使用Indexes构建器在location.geo字段上创建2dsphere索引:

// <MongoCollection setup code here>
collection.createIndex(Indexes.geo2dsphere("location.geo"));

有关Indexes构建器的更多信息,请参阅我们的索引构建器指南。

您可以使用二维欧几里得平面上的xy坐标来存储地理空间数据。 我们将二维平面上的坐标称为“legacy coordinate pairs”。

legacy coordinate pairs 具有以下结构:

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

您的字段应包含一个由两个值组成的数组,其中第一个值代表 x 轴值,第二个值代表 y 轴值。

要插入存储传统坐标对的文档,请创建一个将坐标对值分配给字段的文档。 然后,将该文档传递给insertOne()方法。

以下示例插入一个包含coordinates字段的文档,其中包含传统坐标对:

// Add your MongoCollection setup code here
Document theater = new Document("theaterId", 1204)
.append("coordinates", Arrays.asList(-73.9862, 40.7311));
InsertOneResult result = collection.insertOne(theater);

要学习;了解有关插入文档的更多信息,请参阅插入操作指南。

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

// <MongoCollection setup code here>
collection.createIndex(Indexes.geo2d("coordinates"));

有关Indexes构建器的更多信息,请参阅我们的索引构建器指南。

legacy coordinate pairs有关传统坐标对的更多信息,请参阅有关 的MongoDB Server legacy coordinate pairs手册页面。

提示

支持的操作符

球面 (2dsphere) 和平面 (2d) 索引支持一部分(而非全部)相同查询操作符。有关操作符及其索引兼容性的完整列表,请参阅地理空间查询手册条目

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

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

  • $near

  • $geoWithin

  • $nearSphere

  • $geoIntersects 需要 2dsphere 索引

您可以使用Filters构建器类的near()geoWithin()nearSphere()geoIntersects()实用程序方法在 MongoDB Java 驱动程序中指定这些查询操作符。

有关地理空间查询操作符的更多信息,请参阅地理空间查询手册条目。

有关Filters的更多信息,请参阅我们的筛选器构建器指南。

要指定在地理空间查询中使用的形状,请使用 MongoDB Java 驱动程序的PositionPointLineStringPolygon类。

有关 MongoDB Java 驱动程序中可用的 GeoJSON 形状的完整列表,请参阅 GeoJSON 包 API 文档。

以下示例使用 MongoDB Atlas 样本数据集。您可以学习如何设置自己的免费套餐 Atlas 集群,并在我们的快速入门指南中了解如何加载样本数据集。

示例使用了样本数据集 sample_mflix 数据库中的 theaters 集合。theaters 集合包含 location.geo 字段上的 2dsphere 索引。

这些示例需要进行以下导入:

import java.util.Arrays;
import org.bson.conversions.Bson;
import com.mongodb.client.model.geojson.Point;
import com.mongodb.client.model.geojson.Polygon;
import com.mongodb.client.model.geojson.Position;
import static com.mongodb.client.model.Filters.near;
import static com.mongodb.client.model.Filters.geoWithin;
import static com.mongodb.client.model.Projections.fields;
import static com.mongodb.client.model.Projections.include;
import static com.mongodb.client.model.Projections.excludeId;

您可以 在此处找到 Github上示例的源代码。

要按从最近到最远的顺序搜索并返回文档,请使用Filters构建器类的near()静态实用程序方法。 near()方法使用$near查询运算符构造查询。

以下示例查询距离10,000 5,000中央公园大草坪 到 米之间的剧院。

// Add your MongoClient setup code here
MongoDatabase database = mongoClient.getDatabase("sample_mflix");
MongoCollection<Document> collection = database.getCollection("theaters");
Point centralPark = new Point(new Position(-73.9667, 40.78));
// Creates a query that matches all locations between 5,000 and 10,000 meters from the specified Point
Bson query = near("location.geo", centralPark, 10000.0, 5000.0);
// Creates a projection to include only the "location.address.city" field in the results
Bson projection = fields(include("location.address.city"), excludeId());
// Prints the projected field of the results from the geospatial query as JSON
collection.find(query)
.projection(projection)
.forEach(doc -> System.out.println(doc.toJson()));

上述代码的输出如下所示:

{"location": {"address": {"city": "Bronx"}}}
{"location": {"address": {"city": "New York"}}}
{"location": {"address": {"city": "New York"}}}
{"location": {"address": {"city": "Long Island City"}}}
{"location": {"address": {"city": "New York"}}}
{"location": {"address": {"city": "Secaucus"}}}
{"location": {"address": {"city": "Jersey City"}}}
{"location": {"address": {"city": "Elmhurst"}}}
{"location": {"address": {"city": "Flushing"}}}
{"location": {"address": {"city": "Flushing"}}}
{"location": {"address": {"city": "Flushing"}}}
{"location": {"address": {"city": "Elmhurst"}}}

提示

有趣的事实

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

有关$near操作符的更多信息,请参阅$near 的参考文档。

有关Filters的更多信息,请参阅我们的筛选器构建器指南。

要搜索指定形状内的地理空间数据,请使用Filters构建器类的geoWithin()静态实用程序方法。 geoWithin()方法使用$geoWithin查询运算符构造查询。

以下示例搜索长岛某个地区的电影院。

// Add your MongoCollection setup code here
// Creates a set of points that defines the bounds of a geospatial shape
Polygon longIslandTriangle = new Polygon(Arrays.asList(new Position(-72, 40),
new Position(-74, 41),
new Position(-72, 39),
new Position(-72, 40)));
// Creates a projection to include only the "location.address.city" field in the results
Bson projection = fields(include("location.address.city"), excludeId());
// Creates a query that matches documents containing "location.geo" values within the specified bounds
Bson geoWithinComparison = geoWithin("location.geo", longIslandTriangle);
// Prints the projected field of the results from the geolocation query as JSON
collection.find(geoWithinComparison)
.projection(projection)
.forEach(doc -> System.out.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 的参考文档

有关可在查询中使用的操作符的更多信息,请参阅MongoDB Server手册页面中有关地理空间查询操作符的内容。

后退

指定要返回的字段