面试题答案
一键面试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
}
$addFields
阶段:从日期字段中提取年份和月份。$group
阶段:按年份和月份分组,计算每个月所有产品销售数量的总和。- 第二个
$group
阶段:按年份分组,将每个月的总和整理到数组中,确保数组中每个位置对应相应的月份。 $project
阶段:重塑结果,去掉_id
字段,将年份和月份总和数组整理成合适的格式。- 再次
$group
和$project
阶段:将结果合并为一个文档,以满足题目要求的格式。
上述代码基于 MongoDB 进行聚合操作,实际情况中请根据你使用的数据库和编程语言进行适当调整。