LBS:存储每个地点的经纬度坐标,搜寻附近的地点,建立地理位置索引可提高查询效率
地理位置索引
2d :平面 ‘2d’
2dsphere :球面 ‘2dsphere’
查询方式
2d: near:[x,y] geoWithin box矩形 center 圆形 polygon多边形中
2dsphere:geoNear near geoIntersects geoWithin
数据准备
数据格式
use sample_restaurants;
//多边形
db.neighborhoods.find();
{
_id: ObjectId('55cb9c666c522cafdb053a2d'),
geometry: {
coordinates: [
[
[ -73.96285973961454, 40.61254948646701 ],
[ -73.9638533251958, 40.61243251871314 ],
[ -73.96478112808943, 40.61233092216423 ],
……
[ -73.96356470625155, 40.61623872246746 ],
[ -73.9633609402326, 40.615204428336156 ],
[ -73.96285973961454, 40.61254948646701 ]
]
],
type: 'Polygon'
},
name: 'Ocean Parkway South'
}

数据下载
wget https://atlas-education.s3.amazonaws.com/sampledata.archive
导入数据
//导入数据
mongorestore --archive=sampledata.archive -u admin -p 'mongodb@123' --port=27017
查看导入数据
show dbs;
admin 180.00 KiB
config 72.00 KiB
local 72.00 KiB
sample_airbnb 52.10 MiB
sample_analytics 9.39 MiB
sample_geospatial 996.00 KiB
sample_guides 40.00 KiB
sample_mflix 108.45 MiB
sample_restaurants 5.61 MiB
sample_supplies 968.00 KiB
sample_training 40.67 MiB
sample_weatherdata 2.39 MiB
test 11.98 MiB
添加2dsphere索引
db.restaurants.createIndex({ location: "2dsphere" })
db.neighborhoods.createIndex({ geometry: "2dsphere" })
需要注意的是:mongodb不存在的字段添加索引,但如果GeoJSON 格式不对则会报错:unknown GeoJSON type
要指定 GeoJSON 数据,请使用包含以下内容的嵌入式文档:
-
一个名为
type的字段,用于指定 GeoJSON 对象类型,以及 -
名为
coordinates的字段,指定对象的坐标。<field>: { type: <GeoJSON type> , coordinates: <coordinates> }
查找当前邻近区域
可与多边形的边线重叠
查询与经度-73.93414657、纬度 40.82302903位置相交的区域
db.neighborhoods.findOne(
{ geometry:
{ $geoIntersects:
{
$geometry: { type: "Point", coordinates: [ -73.93414657, 40.82302903 ]}
}
}
}
)
查找街区中所有的餐厅
位于位置内
var neighborhood = db.neighborhoods.findOne(
{ geometry:
{ $geoIntersects:
{ $geometry: { type: "Point", coordinates: [ -73.93414657, 40.82302903 ] }
}
}
}
)
//位于位置内
db.restaurants.find( { location: { $geoWithin: { $geometry: neighborhood.geometry } } } ).count()
按距离查找
即方圆多少以内
centerSphere 的第二个参数接受弧度制的半径(即地球半径英里为单位:赤道半径 3963英里)
db.restaurants.find({ location:
{ $geoWithin:
{ $centerSphere: [ [ -73.93414657, 40.82302903 ], 5 / 3963.2 ] }
}
}
)
按距离查找
按从最近到最远的排序顺序返回距离用户五英里范围内的所有餐厅(一英里等于1609.34米)
var METERS_PER_MILE = 1609.34
db.restaurants.find({ location:
{ $nearSphere:
{ $geometry: { type: "Point", coordinates: [ -73.93414657, 40.82302903 ] },
$maxDistance: 5 * METERS_PER_MILE }
}
}
)
2D索引查询
maxDistance单位是弧度, 地球表面1弧度距离约为6378137米, 0.001弧度距离为6378米 } )
db.restaurants.find( { "address.coord" :
{ $near :
[-73.9925306, 40.7309346 ] ,
$maxDistance : 0.001
} }
,{"address.coord": 1}
)
总结
1.mongodb v2.2以上建议使用2dsphere空间索引
2.需要注意的是:mongodb不存在的字段添加索引,但如果GeoJSON 格式不对则会报错:unknown GeoJSON type
3.GeoJSON 类型有 : Point,LineString,Polygon,MultiPoint,MultiLineString,MultiPolygon,GeometryCollection
4.2d和2dsphere关于maxDistance的度量完全不一样
2d:maxDistance单位是弧度距离约为6378137米。
2dsphere :maxDistance单位是米




