使用地理空间数据
Overview
在本指南中,您可以了解如何使用地理空间数据;数据格式、索引和查询。地理空间数据表示地球表面的地理位置,或欧几里得平面上的数据。
地理空间数据的示例包括:
电影院位置
国家/地区边界
自行车骑行路线
纽约市的狗狗运动区
图表上的点
存储地理空间数据
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}, }}}, }, } Polygon
:位置数组,其中第一个和最后一个位置相同,并包含一些空格。以下Polygon
代表梵蒂冈城内的土地: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 实例。
示例使用了样本数据集 sample_mflix
数据库中的 theaters
集合。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驾驶员处理索引的更多信息,请参阅索引指南。