MongoDB聚合:如何将对象数组合并为单个分组对象
问题描述
现有如下数据结构:
results: [ { name: 'vitor', age: 40, colors: [ 'black', 'white', 'blue' ] }, { name: 'vinicius', age: 32, colors: [ 'green', 'orange', 'blue' ] }, { name: 'pedro', age: 17, colors: [ 'purple' ] }, ]
需要通过MongoDB聚合,将该数组合并为单个对象,把每个属性值分组为数组,目标结果如下:
{ name: ['vitor', 'vinicius', 'pedro'], age: [40, 32, 17], colors: [ 'black', 'white', 'blue', 'green', 'orange', 'purple' ] }
最优聚合方案
最高效的方式是直接在$project阶段使用$reduce合并数组,配合$setUnion对颜色数组去重,避免使用$unwind生成过多中间文档,提升聚合性能。
完整聚合管道代码:
db.collection.aggregate([ { $project: { // 合并所有name字段为数组 name: { $reduce: { input: "$results", initialValue: [], in: { $concatArrays: ["$$value", ["$$this.name"]] } } }, // 合并所有age字段为数组 age: { $reduce: { input: "$results", initialValue: [], in: { $concatArrays: ["$$value", ["$$this.age"]] } } }, // 合并所有colors数组并去重 colors: { $setUnion: { $reduce: { input: "$results", initialValue: [], in: { $concatArrays: ["$$value", "$$this.colors"] } } } }, // 移除默认的_id字段 _id: 0 } } ])
代码说明
$reduce:遍历results数组,将每个文档的name/age/colors逐步合并到初始空数组中。$concatArrays:用于将当前元素(或元素数组)追加到结果数组里。$setUnion:对合并后的colors数组去重,确保每种颜色只出现一次(如果不需要去重,直接去掉$setUnion即可)。$project:最终构造出目标结构,并移除不需要的_id字段。
内容的提问来源于stack exchange,提问作者Vitor Ceolin
相关产品推荐
相关产品推荐

