MongoDB的地理空间索引主要是用来解决“获取空间中(可以是2D平面空间,也可以是球面空间)某一基准点的邻近点”的问题,其核心算法是基于GeoHash的。
坐标
既然要计算空间上的邻近点,那么当然需要在相关的集合中加入特定的字段用以标明坐标。
MongoDB支持两种坐标表示形式,
一种是Double数组,形如:
[ -73.9667, 40.78 ]、[0, 80]
在2D平面中使用时,约定格式为[x, y],
在球面空间使用时,约定格式为[longitude, latitude]
另一种是GeoJSON,简单说来,就是JSON格式,只不过对它里面的字段做了限定,它的格式是这样子的:
{
type: “Point”,
coordinates: [ 40, 5 ]
}
这里的type,指的是当前所代表的几何体类型,
主要有3种独立类型:
Point、LineString、Polygon
和4种集合类型:
MultiPoint、MultiLineString、MultiPolygon、GeometryCollection
对于坐标来说,当然就只能是Point了。
2d、2dsphere
在MongoDB中,想要运用它的地理空间检索,必须给相应字段建立索引,主要有2d、2dsphere这两种索引,
建立的语法分别为:
db.集合名.createIndex({“字段1”: “2d”}) db.集合名.createIndex({“字段2”: “2dsphere”})
这样就给字段1增加了2d索引,给字段2增加了2dsphere索引
$near、$nearSphere
$near、$nearSphere是MongoDB中用来获取某一基准点的邻近点、并且由近至远排好序的操作。他们都支持对2d索引和2dsphere索引的操作,但有如下需要注意的点:
●$near检索时,若标识坐标的字段为2d索引,它传入的基准点的格式必须是Double数组型的;若标识坐标的字段为2dsphere索引,传入的基准点的格式则必须为GeoJSON型。
●对于$nearSphere,若作用在2d索引上,则要求该2d索引必须是建立在集合中GeoJSON型数据的coordinates字段上,且传入的基准点的格式必须是Double数组型的;若作用在2dsphere索引上,则对基准点的格式无要求。
●传入的基准点格式为Double数组时,$minDistance、$maxDistance的计算都是以弧度为单位的;
传入的基准点格式为GeoJSON时,计算是以距离:米为单位的。
返回距离
$near、$nearSphere虽然能够检索出邻近点,并且由近至远排好序,但是这两个操作是不返回距离的。
返回距离需要用到聚合检索中的$geoNear,其使用方法为:
db.集合名.aggregate([{ $geoNear: { near: { type: “Point”, coordinates: [ -73.99279 , 40.719296 ] }, distanceField: “dist.calculated”, maxDistance: 2, query: { type: “public” }, includeLocs: “dist.location”, num: 5, spherical: true } }])
其中,distanceField用来声明计算出的距离所在的字段。
更多详细可以查看MongoDB官网: https://docs.mongodb.com/manual/reference/operator/aggregation/geoNear/