MST

星途 面试题库

面试题:MongoDB聚合管道复杂查询之多层次聚合与数据重塑

仍以'sales'集合为例,现在需要先按照年份对销售数据进行分组,在每个年份组内,再按照月份分组,计算每个月所有产品销售数量的总和,最后将结果重塑为一个以年份为键,月份总和数组为值的文档结构(例如:{ '2023': [100, 150, 200,...], '2024': [80, 90, 120,...] })。请给出完整的聚合管道实现。
40.3万 热度难度
数据库MongoDB

知识考点

AI 面试

面试题答案

一键面试
db.sales.aggregate([
    // 提取年份和月份
    {
        $addFields: {
            year: { $year: "$date" },
            month: { $month: "$date" }
        }
    },
    // 按年份和月份分组,计算每个月的销售数量总和
    {
        $group: {
            _id: { year: "$year", month: "$month" },
            totalSales: { $sum: "$quantity" }
        }
    },
    // 按年份分组,将每个月的总和整理到数组中
    {
        $group: {
            _id: "$_id.year",
            monthlyTotals: {
                $push: {
                    $cond: {
                        if: { $eq: ["$month", 1] },
                        then: "$totalSales",
                        else: 0
                    }
                },
                $push: {
                    $cond: {
                        if: { $eq: ["$month", 2] },
                        then: "$totalSales",
                        else: 0
                    }
                },
                $push: {
                    $cond: {
                        if: { $eq: ["$month", 3] },
                        then: "$totalSales",
                        else: 0
                    }
                },
                $push: {
                    $cond: {
                        if: { $eq: ["$month", 4] },
                        then: "$totalSales",
                        else: 0
                    }
                },
                $push: {
                    $cond: {
                        if: { $eq: ["$month", 5] },
                        then: "$totalSales",
                        else: 0
                    }
                },
                $push: {
                    $cond: {
                        if: { $eq: ["$month", 6] },
                        then: "$totalSales",
                        else: 0
                    }
                },
                $push: {
                    $cond: {
                        if: { $eq: ["$month", 7] },
                        then: "$totalSales",
                        else: 0
                    }
                },
                $push: {
                    $cond: {
                        if: { $eq: ["$month", 8] },
                        then: "$totalSales",
                        else: 0
                    }
                },
                $push: {
                    $cond: {
                        if: { $eq: ["$month", 9] },
                        then: "$totalSales",
                        else: 0
                    }
                },
                $push: {
                    $cond: {
                        if: { $eq: ["$month", 10] },
                        then: "$totalSales",
                        else: 0
                    }
                },
                $push: {
                    $cond: {
                        if: { $eq: ["$month", 11] },
                        then: "$totalSales",
                        else: 0
                    }
                },
                $push: {
                    $cond: {
                        if: { $eq: ["$month", 12] },
                        then: "$totalSales",
                        else: 0
                    }
                }
            ]
        }
    },
    // 重塑结果
    {
        $project: {
            year: "$_id",
            monthlyTotals: 1,
            _id: 0
        }
    },
    {
        $group: {
            _id: null,
            result: {
                $mergeObjects: {
                    $arrayToObject: [
                        [
                            { k: "$year", v: "$monthlyTotals" }
                        ]
                    ]
                }
            }
        }
    },
    {
        $project: {
            _id: 0,
            result: 1
        }
    }
]);

假设集合中的文档结构为:

{
    "date": ISODate("2023-01-15T00:00:00Z"),
    "product": "ProductA",
    "quantity": 10
}
  1. $addFields 阶段:从日期字段中提取年份和月份。
  2. $group 阶段:按年份和月份分组,计算每个月所有产品销售数量的总和。
  3. 第二个 $group 阶段:按年份分组,将每个月的总和整理到数组中,确保数组中每个位置对应相应的月份。
  4. $project 阶段:重塑结果,去掉 _id 字段,将年份和月份总和数组整理成合适的格式。
  5. 再次 $group$project 阶段:将结果合并为一个文档,以满足题目要求的格式。

上述代码基于 MongoDB 进行聚合操作,实际情况中请根据你使用的数据库和编程语言进行适当调整。