在MongoDB中,使用2dsphere索引进行地理空间查询非常简单。首先创建集合并插入带有GeoJSON格式的点数据:db.places.insertMany([{location: {type: "Point", coordinates: [116.4074, 39.9042]}, name: "北京"}, {location: {type: "Point", coordinates: [121.4737, 31.2304]}, name: "上海"}])。然后创建索引:db.places.createIndex({location: "2dsphere"})。查询附近地点:db.places.find({location: {$near: { $geometry: {type: "Point", coordinates: [116.4074, 39.9042]}, $maxDistance: 1000000}}}),这会返回北京周边1公里内的点。
GeoJSON支持
MongoDB完全支持GeoJSON标准,包括Point、LineString、Polygon等多种几何类型。你可以存储复杂的多边形边界,例如城市区域:{type: "Polygon", coordinates: [[[100, 0], [101, 0], [101, 1], [100, 1], [100, 0]]]},然后用$geoIntersects查询相交区域,非常适合地图叠加分析。
$geoWithin查询
查找在特定区域内的点:先定义一个圆形区域{ $geometry: { type: "Polygon", coordinates: [[ [0,0], [0,2], [2,2], [2,0], [0,0] ]] }, $maxDistance: 5 },查询db.places.find({ location: { $geoWithin: { $geometry: { type: "Polygon", coordinates: [...] } } } }),这让空间过滤像写普通查询一样直观。
聚合管道中的地理操作
在聚合中使用$geoNear阶段:db.places.aggregate([ { $geoNear: { near: { type: "Point", coordinates: [116.4074, 39.9042] }, distanceField: "dist", maxDistance: 1000000, spherical: true } } ]),自动计算距离并按近到远排序,完美用于推荐附近商店。
性能优化
2dsphere索引支持高性能查询,即使百万级数据也能秒级响应。复合索引如db.places.createIndex({location: "2dsphere", category: 1})进一步加速,按类别过滤附近餐厅。MongoDB的地理查询引擎基于球面几何,确保全球范围准确。
实际案例:LBS服务
构建基于位置的服务(LBS),存储用户位置和POI,用$nearSphere查询最近的咖啡店:db.users.updateOne({userId: "123"}, {$set: {loc: {type: "Point", coordinates: [lon, lat]}}} ),然后实时匹配,简化了从数据存储到分析的全流程。
FAQ
Q: MongoDB地理查询需要特殊配置吗?
A: 不需要,只需创建2dsphere索引即可,所有现代版本内置支持。
Q: 支持哪些几何类型?
A: 支持GeoJSON的所有类型,包括Point、LineString、Polygon、MultiPoint等。
Q: 如何计算两点距离?
A: 用$geoNear聚合阶段,设置distanceField自动计算米为单位的距离。
Q: 可以查询多边形内部吗?
A: 是,用$geoWithin配合Polygon几何体查询内部点。