面试题答案
一键面试假设使用的是 MongoDB 数据库,以下是使用聚合框架解决该问题的代码:
db.orders.aggregate([
// 展开每个订单中的商品项
{ $unwind: "$orderItems" },
// 计算每个订单中每个商品项的总价
{
$addFields: {
itemTotal: { $multiply: ["$orderItems.quantity", "$orderItems.price"] }
}
},
// 按客户和订单分组,并计算每个订单的总价
{
$group: {
_id: { customer: "$customer", orderDate: "$orderDate" },
totalPrice: { $sum: "$itemTotal" },
orderItems: { $push: "$orderItems" }
}
},
// 按客户分组,并找出每个客户总价最高的订单
{
$sortByCount: "$_id.customer"
},
{
$unwind: "$doc"
},
{
$replaceRoot: { newRoot: "$doc" }
},
{
$sort: { totalPrice: -1 }
},
{
$group: {
_id: "$_id.customer",
maxOrder: { $first: "$$ROOT" }
}
},
// 重新格式化输出
{
$project: {
customer: "$_id",
orderDate: "$maxOrder._id.orderDate",
totalPrice: "$maxOrder.totalPrice",
orderItems: "$maxOrder.orderItems",
_id: 0
}
}
]);
上述聚合操作步骤如下:
- $unwind:展开
orderItems
数组,以便对每个商品项进行操作。 - $addFields:计算每个商品项的总价
itemTotal
。 - $group:按客户和订单分组,并计算每个订单的总价,同时保留订单商品详情。
- $sortByCount 和后续操作:按客户分组,并找出每个客户总价最高的订单。
- $project:重新格式化输出,只保留需要的字段。