mongodb要求2dsphere索引必须基于严格geojson结构({type: "point", coordinates: [lng, lat]}),因该索引仅解析含type和coordinates字段的嵌套对象,不支持纯数组;坐标顺序错为[lat, lng]会导致球面查询结果错误且无报错;索引路径须精确匹配嵌套层级,如"profile.geo"不可简写为"geo"。

GeoJSON 格式,字段值必须是 {type: "Point", coordinates: [longitude, latitude]} 这种结构,否则 $nearSphere、$geoWithin 一类操作根本查不出结果。
为什么不能用 [lng, lat] 数组直接建 2dsphere 索引?
MongoDB 明确拒绝为纯数组字段创建 2dsphere 索引,会报错:can't create 2dsphere index on non-GeoJSON geometry。它只认 type + coordinates 的嵌套结构。
- 写成
{"loc": [116.4, 39.9]}→createIndex({"loc": "2dsphere"})失败 - 必须包装成
{"loc": {"type": "Point", "coordinates": [116.4, 39.9]}}→ 才能成功建索引 - 旧数据迁移只需一层映射:
db.coll.updateMany({}, [{$set: {"loc": {type: "Point", coordinates: "$loc"}}}])
coordinates 顺序写反了会怎样?
经度(longitude)必须在前,纬度(latitude)在后 —— 写成 [39.9, 116.4] 表面能插入、索引也能建,但所有球面查询返回空或错乱结果,且 MongoDB 完全不报错。
-
$nearSphere查北京附近 5km,写反坐标可能返回南美洲的点 - Google Maps、OpenStreetMap 是
[lat, lng],但 MongoDB GeoJSON 强制[lng, lat],别凭直觉抄 - 验证方法:用
db.coll.findOne({"loc.coordinates.0": {$gt: 180}})快速扫出非法经度
嵌套字段怎么建 2dsphere 索引?
索引路径必须精确匹配字段层级,比如数据是 {"profile": {"geo": {"type": "Point", "coordinates": [...]}}},那索引就得建在 "profile.geo",建在 "profile" 或 "geo" 都无效。
-
db.coll.createIndex({"profile.geo": "2dsphere"})✅ -
db.coll.createIndex({"geo": "2dsphere"})❌(查不到,也不报错) - 聚合阶段引用同理:
{$geoNear: {near: {$geometry: {...}}, path: "profile.geo"}} - 建议扁平化:直接用
{"loc": {...}},省去路径错配风险
多边形或线段数据要注意什么?
只要类型是 Polygon 或 LineString,就必须严格满足 GeoJSON 规范,否则插入失败或查询静默跳过。
-
Polygon坐标数组首尾必须相同,且至少 4 个点:[[[0,0],[0,1],[1,1],[0,0]]] -
LineString至少 2 个点,不能少于 2;Point就是单个[lng, lat] - 混存不同类型(同一字段既有
Point又有Polygon)会触发GeometryParseError - 别用
2d索引试图支持多边形 —— 它根本不支持$geoWithin,MongoDB 6.0+ 已逐步弃用











