通过 Amazon DocumentDB 查询地理空间数据 - Amazon DocumentDB

通过 Amazon DocumentDB 查询地理空间数据

本节将介绍可以怎样使用 Amazon DocumentDB 来查询地理空间数据。阅读本节后,您将能够回答如何在 Amazon DocumentDB 中存储、查询和索引化地理空间数据。

概述

地理空间的常见用例涉及来自数据的邻近分析。例如,“查找距离西雅图 50 英里范围内的所有机场”,或“查找距离给定位置最近的餐厅”。Amazon DocumentDB 使用 GeoJSON 规范来表示地理空间数据。GeoJSON 是一个对坐标空间中形状进行 JSON 格式化的开源规范。GeoJSON 坐标捕获经度和纬度,表示在类地球球体上的位置。

索引化和存储地理空间数据

Amazon DocumentDB 使用“点” GeoJSON 类型来存储地理空间数据。每个 GeoJSON 文档(或子文档)通常由两个字段组成:

  • 类型 — 要被表示的形状,它告知 Amazon DocumentDB 如何解释“坐标”字段。目前,Amazon DocumentDB 仅支持点

  • 坐标 — 表示为数组中对象的经纬度对 — [经度、纬度]

Amazon DocumentDB 还使用 2dsphere 索引来索引化地理空间数据。Amazon DocumentDB 支持索引化点。Amazon DocumentDB 支持用 2dsphere 索引化进行邻近查询。

让我们考虑一个场景,即您正在为送餐服务构建一个应用程序。您希望要在 Amazon DocumentDB 中存储各种餐厅的经纬度对。为此,我们首先建议您对地理空间字段创建一个包含经纬度对的索引。

use restaurantsdb db.usarestaurants.createIndex({location:"2dsphere"})

该命令的输出内容类似如下所示:

{ "createdCollectionAutomatically" : true, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 }

创建索引后,您可以开始将数据插入 Amazon DocumentDB 集合。

db.usarestaurants.insert({ "state":"Washington", "city":"Seattle", "name":"Thai Palace", "rating": 4.8, "location":{ "type":"Point", "coordinates":[ -122.3264, 47.6009 ] } }); db.usarestaurants.insert({ "state":"Washington", "city":"Seattle", "name":"Noodle House", "rating": 4.8, "location":{ "type":"Point", "coordinates":[ -122.3517, 47.6159 ] } }); db.usarestaurants.insert({ "state":"Washington", "city":"Seattle", "name":"Curry House", "rating": 4.8, "location":{ "type":"Point", "coordinates":[ -121.4517, 47.6229 ] } });

查询地理空间数据

Amazon DocumentDB 支持对地理空间数据的邻近查询、包含查询和交叉点查询。一个良好的邻近查询示例是查找距另一个点(城市)小于某个距离且大于某个距离的所有点(所有机场)。一个良好的包含项查询示例是查找位于指定区域/多边形(纽约州)的所有点(所有机场)。一个良好的交叉点查询示例是查找与某个点(城市)相交的多边形(州)。您可以使用以下地理空间运算符从数据中获取见解。

  • $nearSphere - $nearSphere 是一个查找运算符,支持查找距 GeoJSON 点最近处到最远处的点。

  • $geoNear - $geoNear 是一个聚合运算符,支持计算以米为单位的距 GeoJSON 点的距离。

  • $minDistance - $minDistance 是一个查找运算符,结合 $nearSphere$geoNear 一起用于筛选距中心点至少指定最小距离的文档。

  • $maxDistance - $maxDistance 是一个查找运算符,结合 $nearSphere$geoNear 一起用于筛选距中心点至多指定最大距离的文档。

  • $geoWithin - $geoWithin 是一个查找运算符,支持查找包含具有以下地理空间数据的文档,这些数据完全存在于指定形状(如多边形)范围内。

  • $geoIntersects - $geoIntersects 是一个查找运算符,支持查找其地理空间数据与指定 GeoJSON 对象相交的文档。

注意

$geoNear$nearSphere 要求您在邻近查询中使用的 GeoJSON 字段上有 2dsphere 索引。

示例 1

在此示例中,您将学习如何查找按照距某地址(点)最近距离排序的所有餐厅(点)。

要执行这样的查询,您可以使用 $geoNear 计算一组点距另一点的距离。您也可以添加 distanceMultiplier 来测量以千米计的距离。

db.usarestaurants.aggregate([ { "$geoNear":{ "near":{ "type":"Point", "coordinates":[ -122.3516, 47.6156 ] }, "spherical":true, "distanceField":"DistanceKilometers", "distanceMultiplier":0.001 } } ])

上述命令将返回按照距指定点的距离(最近到最远)排序的餐厅。该命令的输出内容类似如下所示

{ "_id" : ObjectId("611f3da985009a81ad38e74b"), "state" : "Washington", "city" : "Seattle", "name" : "Noodle House", "rating" : 4.8, "location" : { "type" : "Point", "coordinates" : [ -122.3517, 47.6159 ] }, "DistanceKilometers" : 0.03422834547294996 } { "_id" : ObjectId("611f3da185009a81ad38e74a"), "state" : "Washington", "city" : "Seattle", "name" : "Thai Palace", "rating" : 4.8, "location" : { "type" : "Point", "coordinates" : [ -122.3264, 47.6009 ] }, "DistanceKilometers" : 2.5009390081704277 } { "_id" : ObjectId("611f3dae85009a81ad38e74c"), "state" : "Washington", "city" : "Seattle", "name" : "Curry House", "rating" : 4.8, "location" : { "type" : "Point", "coordinates" : [ -121.4517, 47.6229 ] }, "DistanceKilometers" : 67.52845344856914 }

要限制查询中的结果数量,可使用 limitnum 选项。

limit:

db.usarestaurants.aggregate([ { "$geoNear":{ "near":{ "type":"Point", "coordinates":[ -122.3516, 47.6156 ] }, "spherical":true, "distanceField":"DistanceKilometers", "distanceMultiplier":0.001, "limit": 10 } } ])

num:

db.usarestaurants.aggregate([ { "$geoNear":{ "near":{ "type":"Point", "coordinates":[ -122.3516, 47.6156 ] }, "spherical":true, "distanceField":"DistanceKilometers", "distanceMultiplier":0.001, "num": 10 } } ])
注意

$geoNear stage 支持 limitnum 选项来指定要返回的最大文档数。如果未指定 limitnum 选项,则 $geoNear 默认最多返回 100 个文档。如果存在 $limit stage 的值且此值小于 100,则文档数会被此值覆盖。

示例 2

在此示例中,您将学习如何查找距特定地址(点)2 千米范围内的所有餐厅(点)。要执行此类查询,您可以在距 GeoJSON 点的最小值 $minDistance 和最大值 $maxDistance 范围内使用 $nearSphere

db.usarestaurants.find({ "location":{ "$nearSphere":{ "$geometry":{ "type":"Point", "coordinates":[ -122.3516, 47.6156 ] }, "$minDistance":1, "$maxDistance":2000 } } }, { "name":1 })

上面的命令将返回距指定点最大距离 2 千米的餐厅。该命令的输出内容类似如下所示

{ "_id" : ObjectId("611f3da985009a81ad38e74b"), "name" : "Noodle House" }

限制

Amazon DocumentDB 不支持对多边形、LineString、MultiPoint、MultiPolygon、MultilityString 和 GeometryCollection 查询或索引化。