地理空间查询
在本页面:
地理空间数据
在MongoDB中,您可以将地理空间数据存储为 GeoJSON 对象或遗留坐标对。
GeoJSON对象
要计算类地球体的几何形状,请将位置数据存储为 GeoJSON 对象 。
要指定 GeoJSON 数据,请使用嵌入的文档:
-
一个名为 type 的字段,用于指定 GeoJSON 对象类型
-
一个名为坐标的字段,用于指定对象的坐标。
如果指定纬度和经度坐标,请先列出经度,然后再列出纬度:
-
有效的经度值在 -180 到 180 之间(包括两者)。
-
有效的纬度值在 -90 到 90 之间(包括两者之间)。
<field>: { type: <GeoJSON type> , coordinates: <coordinates> }
例如,要指定 GeoJSON Point ::
location: {
type: "Point",
coordinates: [-73.856077, 40.848447]
}
有关MongoDB支持的 GeoJSON 对象的列表以及示例,请参阅 GeoJSON 对象 。
对 GeoJSON 对象的MongoDB地理空间查询是在球体上计算的; MongoDB使用 WGS84 参考系统对 GeoJSON 对象进行地理空间查询。
旧版坐标对
在欧几里德平面上计算距离,请将您的位置数据存储为旧坐标对并使用
2d
索引。 通过将数据转换为GeoJSON
Point类型,MongoDB支持通过
2dsphere
索引对旧坐标对进行球面计算。
要将数据指定为旧版坐标对,可以使用数组(首选)或嵌入式文档。
通过数组指定(首选):
<field>: [ <x>, <y> ]
如果指定纬度和经度坐标,请先列出经度,然后再列出纬度; 即:
<field>: [<longitude>, <latitude> ]
-
有效的经度值在 [-180 180] 。
-
有效的纬度值在 [-90 90] 。
通过嵌入式文档指定:
<field>: { <field1>: <x>, <field2>: <y> }
如果指定纬度和经度坐标,第一个字段必须包含经度值,而第二个字段必须包含纬度值;即。
<field>: { <field1>: <longitude>, <field2>: <latitude> }
- 有效的经度值在 [-180 180] 。
- 有效的纬度值在 [-90 90] 。
为了指定旧版坐标对,数组比嵌入式文档更可取,因为某些语言不能保证关联地图的排序。
地理空间索引
MongoDB提供以下地理空间索引类型以支持地理空间查询。
2dsphere
索引支持查询,该查询可在类似地球的球体上计算几何形状。
要创建
2dsphere
索引,请使用
db.collection.createIndex()
方法并指定字符串文字“
2dsphere
”作为索引类型:
db.collection.createIndex( { <location field> : "2dsphere" } )
其中
<
location field
>
是其值为GeoJSON对象或旧版坐标对的字段。
有关
2dsphere
索引的更多信息,请参见
2dsphere
索引。
2d
索引支持在
二维平面上计算几何的查询
.尽管索引可以支持在球上进行计算的
$nearSphere
查询,但如果可能,请对球面查询使用
2dsphere
索引。
要创建
2d
索引,请使用
db.collection.createIndex()
方法,将location字段指定为键,并将字符串文字
“ 2d”
指定为索引类型:
db.collection.createIndex( { <location field> : "2d" } )
其中
<
location field
>
是一个值为
旧版坐标对
的字段。
有关 2d 索引的更多信息,请参见 2d 索引 。
地理空间索引和分片集合
分片集合时,不能将地理空间索引用作分片键。但是,可以通过使用不同的字段作为分片键在分片集合上创建地理空间索引。
分片集合支持以下地理空间操作:
-
$geoNear 聚集阶段
-
$near 和 $nearSphere 查询运算符(从MongoDB 4.0开始).
从MongoDB 4.0开始,分片集合支持
$near
和
$nearSphere
查询。
在早期的MongoDB版本中,分片集合不支持
$near
和
$nearSphere
查询。相反,对于分片群集,必须使用
$geoNear
聚合阶段或
geoNear
命令(在MongoDB
4.0及更低版本中可用)。
您还可以使用
$geoWithin
和
$geoIntersect
查询分片群集的地理空间数据。
涵盖查询
地理空间查询
[success] Note
对于球形查询,请使用 2dsphere 索引结果。
将 2d 索引用于球形查询可能会导致错误的结果,例如将 2d 索引用于环绕两极的球形查询。
地理空间查询操作符
MongoDB提供以下地理空间查询操作符:
| 名字 | 说明 |
|---|---|
| $geoIntersects |
选择与
GeoJSON
几何形状相交的几何形状。
2dsphere
索引支持
$geoIntersects
.
|
| $geoWithin |
选择边界
GeoJSON几何
图形内的几何图形。
2dsphere
和2d索引支持
$geoWithin
.
|
| $near |
返回球体上某个点附近的地理空间对象。
需要地理空间索引。
2dsphere
和
2d
索引支持
$near
.
|
| $nearSphere |
返回接近球体上某一点的地理空间对象。需要地理空间索引。
2dsphere
和
2d
索引支持
$nearSphere
.
|
有关更多细节(包括示例),请参见个别参考页面。
地理空间聚集阶段
MongoDB提供以下地理空间聚合管道阶段:
| 步骤 | 说明 |
|---|---|
| $geoNear |
根据与地理空间点的接近程度返回有序的文档流。
合并了地理空间数据的
$match
,
$sort
, 和
$limit
功能。
输出文档包括附加距离字段,并且可以包括位置标识符字段。
$geoNear
需要一个
地理空间索引
。
|
有关更多详细信息(包括示例),请参见 $geoNear 参考页。
地理空间模型
MongoDB地理空间查询可以解释平面或球体上的几何。
2dsphere 索引仅支持球形查询(即解释球形表面几何形状的查询)。
2d 索引支持平面查询(即解释平面上的几何图形的查询)和某些球形查询。 虽然 2d 索引支持某些球形查询,但是将 2d 索引用于这些球形查询可能会导致错误。 如果可能,请对球形查询使用 2dsphere 索引。
下表列出了每个地理空间操作所使用的地理空间查询运算符,受支持的查询:
| 操作方式 | 球面/平面查询 | 笔记 |
|---|---|---|
| $near ( GeoJSON centroid point in this line and the following line, 2dsphere index) | 球形 | 另请参见 $nearSphere 运算符,该运算符与GeoJSON和2dsphere索引一起使用时提供相同的功能。 |
| $near ( legacy coordinates , 2d index) | 平面 | |
| $nearSphere ( GeoJSON point, 2dsphere index) | 球形 | 提供与使用GeoJSON点和2dsphere索引的$ near操作相同的功能。对于球形查询,最好使用$ nearSphere而不是$ near运算符,后者在名称中显式指定球形查询。 |
| $nearSphere ( legacy coordinates , 2d index) | 球形 | 请改用 GeoJSON 点。 |
| $geoWithin : { $geometry : … } | 球形 | |
| $geoWithin : { $box : … } | 平面 | |
| $geoWithin : { $polygon : … } | 平面 | |
| $geoWithin : { $center : … } | 平面 | |
| $geoWithin : { $centerSphere : … } | 球形 | |
| $geoIntersects | 球形 | |
| $geoNear aggregation stage ( 2dsphere index) | 球形 | |
| $geoNear aggregation stage ( 2d index) | 平面 |
例子
用以下文档创建一个集合 places :
db.places.insert( {
name: "Central Park",
location: { type: "Point", coordinates: [ -73.97, 40.77 ] },
category: "Parks"
} );
db.places.insert( {
name: "Sara D. Roosevelt Park",
location: { type: "Point", coordinates: [ -73.9928, 40.7193 ] },
category: "Parks"
);
db.places.insert( {
name: "Polo Grounds",
location: { type: "Point", coordinates: [ -73.9375, 40.8303 ] },
category: "Stadiums"}
);
以下操作在 location 字段上创建 2dsphere 索引:
db.places.createIndex( { location: "2dsphere" } )
以下查询使用
$near
运算符返回距指定GeoJSON点至少1000米,最多5000米的文档,并按从最近到最远的顺序排序:
db.places.find(
{
location:
{ $near:
{
$geometry: { type: "Point", coordinates: [ -73.9667, 40.78 ] },
$minDistance: 1000,
$maxDistance: 5000
}
}
}
)
以下操作使用 geoNea r聚合操作返回与查询过滤器 {category:“ Parks”} 匹配的文档,这些文档按从最接近指定GeoJSON点的最近到最远的顺序排序:
db.places.aggregate( [
{
$geoNear: {
near: { type: "Point", coordinates: [ -73.9667, 40.78 ] },
spherical: **true**,
query: { category: "Parks" },
distanceField: "calcDistance"
}
}
])
译者:杨帅
校对:杨帅