如何使用Mongoose按相同坐标值分组返回文档
Mongoose按坐标完全匹配分组聚合实现
示例文档结构
{ "_id":"62a1a47ee3a37826bb647518", "lid":"629df665563f56ec1a638ea0", "date": "7", "time": "1654583101416", "location": { "type": "Point", "coordinates": [75.26438,11.29343] } }
需求:对上述结构的MongoDB文档做分组查询,location.coordinates坐标值完全相同的文档归为同一分组,每个分组仅返回1条结果文档。
实现代码
直接用MongoDB聚合管道的$group阶段即可,数组类型值作为分组键时,MongoDB会自动判断数组元素、顺序完全一致才归为同组:
// 替换成你实际定义的Mongoose模型名 const result = await TrackModel.aggregate([ { $group: { // 以经纬度坐标数组作为分组唯一键 _id: "$location.coordinates", // 取每组第一条完整文档,要取最后一条就把$first换成$last targetDoc: { $first: "$$ROOT" } } }, { // 可选阶段:把嵌套的targetDoc提升为顶层结构,返回格式和普通find查询结果一致 $replaceRoot: { newRoot: "$targetDoc" } } ])
注意点
- 该方案仅对完全相等的坐标生效,如果坐标存在浮点精度差(比如
11.293430001和11.293429999),不会被判定为同组。如果有精度误差场景,需要先在聚合中对经纬度做指定位数的截断,或者转GeoHash编码后再分组。 - 如果需要自定义每组返回的内容,可以在
$group阶段单独配置字段规则,比如要统计同坐标点的文档数量,加count: { $sum: 1 }即可;要取同坐标下最新时间的文档,可以配合$max算子对time字段做匹配。 - 2dsphere地理索引不支持聚合分组阶段的索引命中,如果集合数据量超过百万级,建议冗余存储经度、纬度两个独立数值字段,用这两个字段作为分组键可以大幅提升查询效率。
内容的提问来源于stack exchange,提问作者Anand S
相关产品推荐
相关产品推荐

