MongoDB中按城市分组GeoJSON点生成POLYGON的实现咨询
嘿,这问题我熟!MongoDB完全支持按城市分组生成POLYGON要素,你之前报错是因为在聚合的$group阶段用错了方式——直接引用geom字段不行,因为分组阶段要求字段必须是累加器对象(比如$push、$sum这类),而你直接放了普通字段,所以才会触发那个错误。
下面给你两种可行的方案,按需选择:
方案1:手动生成闭合多边形(适合任意MongoDB版本)
如果你的MongoDB版本比较旧,或者需要自定义多边形的点连接方式,可以先收集每个城市的所有坐标,再构造符合GeoJSON规范的POLYGON(注意POLYGON要求坐标数组首尾必须相同,形成闭合图形):
db.yourCollection.aggregate([ // 第一步:按city分组,收集所有点的坐标 { $group: { _id: "$city", points: { $push: "$geom.coordinates" } // 用$push累加坐标,这是合法的累加器操作 } }, // 第二步:给坐标数组添加首尾相同的点,确保多边形闭合 { $addFields: { closedPoints: { $concatArrays: [ "$points", [ { $arrayElemAt: [ "$points", 0 ] } ] // 把第一个点加到数组末尾 ] } } }, // 第三步:构造POLYGON类型的GeoJSON对象 { $addFields: { polygon: { type: "Polygon", coordinates: [ "$closedPoints" ] // POLYGON的coordinates是二维数组,外层包一层数组 } } }, // 可选:调整输出结构,让结果更清晰 { $project: { _id: 0, city: "$_id", polygon: 1 } } ])
方案2:生成凸包多边形(MongoDB 4.2+推荐)
如果你的MongoDB版本是4.2或以上,推荐用$convexHull聚合操作符——它能自动基于一组点生成凸包多边形,避免手动生成可能出现的自相交问题,结果更实用:
db.yourCollection.aggregate([ // 按city分组,收集所有完整的Point类型GeoJSON对象 { $group: { _id: "$city", points: { $push: "$geom" } } }, // 用$convexHull直接生成凸包多边形 { $addFields: { polygon: { $convexHull: "$points" } } }, // 调整输出结构 { $project: { _id: 0, city: "$_id", polygon: 1 } } ])
为什么之前会报错?
你之前在$group阶段可能直接写了类似geom: "$geom"的代码,这不符合MongoDB的聚合规则——$group阶段的字段必须是累加器(比如$push、$sum、$avg),不能直接引用原始字段。用$push把每个城市的点收集起来,就符合要求了。
内容的提问来源于stack exchange,提问作者Haider
相关产品推荐
相关产品推荐

