MongoDB不指定details子字段如何聚合得到各属性对应值数组
实现方案
核心思路是先把details数组内的动态字段全部拆解为可聚合的键值对结构,完成值收集后再重新组装为目标格式,全程不需要硬编码指定flavour、weight等具体字段名。
聚合管道代码
db.collection.aggregate([ // 第一步:拆分所有文档的details数组,得到每个独立的details子对象 { $unwind: "$details" }, // 第二步:把details子对象转为键值对数组,再拆分得到单组键值结构 { $replaceRoot: { newRoot: "$details" } }, { $project: { kv: { $objectToArray: "$$ROOT" } } }, { $unwind: "$kv" }, // 第三步:按字段名分组,收集所有对应值存入数组 { $group: { _id: "$kv.k", values: { $push: "$kv.v" } } }, // 第四步:重新组装为目标结构 { $group: { _id: null, details: { $push: { k: "$_id", v: "$values" } } } }, { $project: { _id: 0, details: { $arrayToObject: "$details" } } } ])
步骤说明
$unwind拆分details数组后,每个原文档的details子对象都会变成独立文档$objectToArray可以将任意对象转为[{k:"字段名",v:"字段值"}]的结构,无需提前知道字段名- 第一次分组按字段名聚合,把同字段的所有值收集到同一个数组
- 第二次分组把所有键值对重新整合,用
$arrayToObject转回目标对象结构 - 如果需要对值去重,把
$push换成$addToSet即可
内容的提问来源于stack exchange,提问作者user16690818
相关产品推荐
相关产品推荐

