MongoDB聚合实现多文档车辆字段去重及各品牌数量统计
问题原因
你当前的聚合管道将$group阶段的_id设为null,会把所有$unwind展开后的车辆记录聚合到同一个分组中,仅能返回全量数据维度的去重字段、全局价格极值,无法拆分出单个品牌维度的计数统计。
实现方案
使用$facet阶段可以在单次聚合查询中同时完成「全局去重字段提取」和「分品牌车辆数统计」两个目标,无需多次扫描集合,执行效率更高,完全适配MongoDB 5.3.1社区版的版本要求。
完整聚合管道代码如下:
[ { '$match': { // 保留原有筛选逻辑即可 } }, { '$unwind': { 'path': '$Vehicles' // 若存在Vehicles为空数组的客户文档,可追加'preserveNullAndEmptyArrays': false过滤空值 } }, { '$facet': { // 分支1:统计全局维度的去重字段、价格极值 'globalStats': [ { '$group': { '_id': null, 'makes': { '$addToSet': '$Vehicles.Manufacturer' }, 'models': { '$addToSet': '$Vehicles.Model' }, 'transmission': { '$addToSet': '$Vehicles.Transmission' }, 'minPrice': { '$min': '$Vehicles.Price' }, 'maxPrice': { '$max': '$Vehicles.Price' } } } ], // 分支2:统计每个品牌对应的车辆总数 'makeVehicleCounts': [ { '$group': { '_id': '$Vehicles.Manufacturer', 'totalVehicles': { '$sum': 1 } } }, { '$sort': { 'totalVehicles': -1 } // 可选配置:按车辆数倒序排列结果 }, { '$project': { '_id': 0, 'makeName': '$_id', 'totalVehicles': 1 } } // 可选配置:格式化输出字段,将品牌名从_id字段提取为独立字段 ] } } ]
返回结果结构说明
查询返回的单条文档中会包含两个字段:
globalStats:长度为1的数组,内部对象包含全量去重后的品牌列表、车型列表、变速箱类型列表,以及全局最低/最高车辆售价makeVehicleCounts:数组结构,每个对象对应一个品牌的名称和该品牌下的车辆总数
可选简化方案
如果你不需要在同一次查询中返回全局去重列表,仅需要统计各品牌的车辆总数,可以直接把原有$group阶段的_id替换为$Vehicles.Manufacturer即可,管道代码如下:
[ { '$match': { // 原有筛选逻辑 } }, { '$unwind': '$Vehicles' }, { '$group': { '_id': '$Vehicles.Manufacturer', 'totalVehicles': { '$sum': 1 } } }, { '$sort': { 'totalVehicles': -1 } } ]
注意:如果客户文档中存在
Vehicles字段为空数组、字段缺失的情况,建议在$unwind阶段设置preserveNullAndEmptyArrays: false,避免空值进入后续统计阶段导致计数异常。
内容的提问来源于stack exchange,提问作者Strontium_99
相关产品推荐
相关产品推荐

