MongoDB嵌套对象文档的多层聚合实现方案咨询
MongoDB多层嵌套聚合解决方案
刚好遇到过类似的多层嵌套数组聚合需求,咱们一步步来实现你要的结果:
完整聚合管道代码
db.your_collection_name.aggregate([ // 第一步:按date分组,汇总顶层核心数据,收集所有订单 { $group: { _id: "$date", total_income: { $sum: "$income" }, total_num_orders: { $sum: "$num_orders" }, all_orders: { $push: "$orders" } } }, // 展开嵌套的订单数组,得到单个订单对象 { $unwind: "$all_orders" }, { $unwind: "$all_orders" }, // 展开每个订单下的产品数组,方便按产品名称汇总数量 { $unwind: "$all_orders.products" }, // 第二步:按日期、订单类型、产品名称分组,汇总产品数量和订单维度数据 { $group: { _id: { date: "$_id", order_type: "$all_orders.type", product_name: "$all_orders.products.name" }, total_income: { $first: "$total_income" }, total_num_orders: { $first: "$total_num_orders" }, order_income_sum: { $sum: "$all_orders.income" }, order_num_products_sum: { $sum: "$all_orders.num_products" }, product_amount_sum: { $sum: "$all_orders.products.amount" } } }, // 第三步:按日期、订单类型分组,重组产品数组并计算单产品均价 { $group: { _id: { date: "$_id.date", order_type: "$_id.order_type" }, total_income: { $first: "$total_income" }, total_num_orders: { $first: "$total_num_orders" }, order_income_sum: { $first: "$order_income_sum" }, order_num_products_sum: { $first: "$order_num_products_sum" }, products: { $push: { name: "$_id.product_name", amount: "$product_amount_sum" } } } }, { $addFields: { avg_product_price: { $round: [ { $divide: [ "$order_income_sum", "$order_num_products_sum" ] }, 2 ] } } }, // 第四步:按日期分组,重组订单数组并计算订单均价 { $group: { _id: "$_id.date", income: { $first: "$total_income" }, num_orders: { $first: "$total_num_orders" }, orders: { $push: { type: "$_id.order_type", income: "$order_income_sum", num_products: "$order_num_products_sum", avg_product_price: "$avg_product_price", products: "$products" } } } }, { $addFields: { avg_order_amount: { $round: [ { $divide: [ "$income", "$num_orders" ] }, 2 ] } } }, // 调整输出字段结构,匹配预期结果 { $project: { _id: 0, date: "$_id", income: 1, num_orders: 1, avg_order_amount: 1, orders: 1 } } ])
关键步骤拆解
- 第一层分组:先把同日期的所有文档聚合到一起,算出顶层的总收益、总订单数,同时把所有订单对象收集到一个数组里,方便后续拆分处理。
- 多层展开:连续两次
$unwind把嵌套的订单数组拆成单个订单对象,再展开每个订单下的产品数组,这样就能精准按产品名称汇总数量。 - 产品维度聚合:按「日期-订单类型-产品名称」分组,算出每个产品的总销量,同时累加对应订单类型的收益和产品总数。
- 订单类型聚合:按「日期-订单类型」分组,把同一类型下的产品重新组合成数组,并用「订单类型总收益/总产品数」算出单产品均价,保留两位小数。
- 顶层最终聚合:回到日期维度,把不同类型的订单重新组合成数组,用「总收益/总订单数」算出订单均价,最后调整输出字段结构,完全匹配你要的结果。
把代码里的your_collection_name换成你的集合名,运行就能得到预期的聚合结果啦!
内容的提问来源于stack exchange,提问作者Amit Aisikowitz
相关产品推荐
相关产品推荐

