处理地理空间数据
概述
在本指南中,您可以学习如何处理地理空间数据;数据格式、索引和查询。地理空间数据表示地球表面上的地理位置或欧几里得平面上的数据。
地理空间数据的例子包括
电影院的位置
国家边界
自行车骑行路线
纽约市的狗运动区域
图上的点
存储地理空间数据
在MongoDB中,所有地理空间数据都存储在以下格式之一中
GeoJSON,一种在类似地球的球体上表示地理空间数据的格式。
传统坐标对,一种在欧几里得平面上表示地理空间数据的格式。
GeoJSON
使用GeoJSON存储表示地球类球体上地理空间信息的数据。GeoJSON由一个或多个位置和一个类型组成。
位置
位置表示地球上的一个单独地点,并在代码中以包含以下值的数组形式存在
第一个位置是经度(必需)
第二个位置是纬度(必需)
第三个位置是海拔(可选)
以下是美国纽约市纽约的MongoDB总部的位置
[]float64{-73.986805, 40.7620853}
重要
经度然后是纬度
GeoJSON按照先经度后纬度的顺序排序坐标。这可能会令人惊讶,因为地理坐标系统惯例通常先列出纬度后列出经度。请确保检查您正在使用的任何其他工具的格式。流行的工具,如OpenStreetMap和Google Maps,将坐标先列出纬度后列出经度。
类型
您的GeoJSON对象的类型决定了它所表示的几何形状。几何形状由位置组成。
以下是一些常见的GeoJSON类型以及如何使用位置指定它们
Point
:一个单独的位置。以下Point
表示MongoDB总部的位置bson.D{ {"name", "MongoDB HQ"}, {"location", bson.D{ {"type", "Point"}, {"coordinates", []float64{-73.986805, 40.7620853}}, }}, } LineString
:由两个或更多位置组成的数组,形成一个线段序列。一个LineString
可以表示路径、路线、边界或任何其他线性地理空间数据。以下LineString
表示中国长城的一段:bson.D{ {"name", "Great Wall of China"}, {"location", bson.D{ {"type", "LineString"}, {"coordinates", [][]float64{ {116.572, 40.430}, {116.570, 40.434}, {116.567, 40.436}, {116.566, 40.441}, }}}, }, } 多边形
:一个位置数组,其中第一个和最后一个位置相同,并包围一些空间。以下多边形
代表 梵蒂冈城内的土地:bson.D{ {"name", "Vatican City"}, {"location", bson.D{ {"type", "Polygon"}, {"coordinates", [][][]float64{{ {12.446086, 41.901977}, {12.457952, 41.901559}, {12.455375, 41.907351}, {12.449863, 41.905186}, {12.446086, 41.901977}, }}}, }}, }
要了解您可以在 MongoDB 中使用的 GeoJSON 类型,请参阅 GeoJSON 手册条目。
有关 GeoJSON 的确切信息,请参阅 官方 IETF 规范。
旧坐标对
使用旧坐标对来存储表示二维欧几里得平面上地理空间信息的数据。
您的字段应包含一个包含两个值的数组,其中第一个代表 x
轴值,第二个代表 y
轴值。
bson.D{{"center", []int16{0, 0}}}
有关旧坐标对的更多信息,请参阅MongoDB服务器手册中的旧坐标对页面。
地理空间索引
要启用对地理空间数据的查询,必须创建与数据格式相对应的索引。以下索引类型支持地理空间查询
2dsphere
用于GeoJSON数据2d
用于旧坐标对
2dsphere
要查询存储在GeoJSON格式中的数据,将包含type
和coordinates
字段的字段添加到2dsphere
索引。以下示例在location
字段上创建了一个2dsphere
索引
indexModel := mongo.IndexModel{ Keys: bson.D{{"location", "2dsphere"}}, } name, err := coll.Indexes().CreateOne(context.TODO(), indexModel) if err != nil { panic(err) }
2d
要查询以旧坐标对存储的数据,您必须将包含旧坐标对的字段添加到2d
索引中。以下示例在coordinates
字段上创建了一个2d
索引
indexModel := mongo.IndexModel{ Keys: bson.D{{"location.coordinates", "2d"}}, } name, err := coll.Indexes().CreateOne(context.TODO(), indexModel) if err != nil { panic(err) }
地理空间查询
要执行地理空间查询,创建一个包含字段名和地理空间查询运算符的查询过滤器。您可以指定某些地理空间查询运算符的附加选项,以限制返回的文档。
如果您尚未这样做,您必须创建地理空间索引以启用地理空间查询。
查询运算符
要查询您的地理空间数据,请使用以下查询运算符之一
$near
$geoWithin
$nearSphere
$geoIntersects
需要一个2dsphere索引
当使用$near
运算符时,您可以指定以下距离运算符
$minDistance
$maxDistance
当使用$geoWithin
运算符时,您可以指定以下形状运算符
$box
$polygon
$center
$centerSphere
有关地理空间查询运算符的更多信息,请参阅地理空间查询的手动条目。
示例
以下示例使用MongoDB Atlas的样本数据集。您可以通过遵循Atlas入门指南将样本数据集加载到MongoDB Atlas的免费层数据库中,或者您可以将样本数据集导入到本地的MongoDB实例中。
示例使用样本数据集中的theaters
集合,位于sample_mflix
数据库中。该theaters
集合在location.geo
字段上有一个2dsphere
索引。
基于邻近性查询
以下示例查询距离纽约市纽约 MongoDB 总部 1000 米内的具有 location.geo
字段的文档。它按从近到远的顺序返回文档。
mongoDBHQ := bson.D{{"type", "Point"}, {"coordinates", []float64{-73.986805, 40.7620853}}} filter := bson.D{ {"location.geo", bson.D{ {"$near", bson.D{ {"$geometry", mongoDBHQ}, {"$maxDistance", 1000}, }}, }}, } var places []bson.D output, err := coll.Find(context.TODO(), filter) if err = output.All(context.TODO(), &places); err != nil { panic(err) } for _, place := range places { res, _ := bson.MarshalExtJSON(place, false, false) fmt.Println(string(res)) }
{"_id":{...},"theaterId":1908,"location":{"address":{...},"geo":{"type":"Point","coordinates":[-73.983487,40.76078]}}} {"_id":{...},"theaterId":1448,"location":{"address":{...},"geo":{"type":"Point","coordinates":[-73.982094,40.769882]}}}
在范围内查询
以下示例查询位于纽约市纽约MongoDB总部2000米至3000米范围内的具有location.geo
字段的文档。结果按距离最近到最远排序。
mongoDBHQ := bson.D{{"type", "Point"}, {"coordinates", []float64{-73.986805, 40.7620853}}} filter := bson.D{ {"location.geo", bson.D{ {"$nearSphere", bson.D{ {"$geometry", mongoDBHQ}, {"$minDistance", 2000}, {"$maxDistance", 3000}, }}, }}, } var places []bson.D output, err := coll.Find(context.TODO(), filter) if err = output.All(context.TODO(), &places); err != nil { panic(err) } for _, place := range places { res, _ := bson.MarshalExtJSON(place, false, false) fmt.Println(string(res)) }
{"_id":{...},"theaterId":482,"location":{...},"geo":{"type":"Point","coordinates":[-73.99295,40.74194]}}}
其他资源
有关使用地理空间数据的信息,请参阅地理空间数据手册条目。
有关支持的GeoJSON类型的更多信息,请参阅GeoJSON手册条目。
有关地理空间查询运算符的更多信息,请参阅地理空间查询手册条目。
有关使用Go驱动程序处理索引的更多信息,请参阅索引指南.