跳到主要内容

场景

2025年02月28日
柏拉文
越努力,越幸运

一、电商平台订单统计


1.1 认识

电商平台订单统计: 设计一个 MongoDB 聚合查询,统计某个时间段内,每个用户的订单总数、总金额,并按订单金额从高到低排序。

1.2 实现

db.orders.aggregate([
{ $match: { orderDate: { $gte: ISODate("2024-01-01"), $lt: ISODate("2024-12-31") } } },
{ $group: {
_id: "$userId",
totalAmount: { $sum: "$orderAmount" },
orderCount: { $sum: 1 }
}},
{ $sort: { totalAmount: -1 } }
])
  1. 解释 $match 在管道中的位置是否会影响性能。

  2. 询问 $group 之后数据如何排序,以及 MongoDB 是否会对 _id 自动排序。

  3. 询问如果 orderAmount 为空或缺失,该查询会如何表现?如何处理?

二、社交平台用户点赞查询


2.1 认识

社交平台用户点赞查询: 设计一个 MongoDB 聚合查询,查询某个用户点赞过的帖子信息,包含帖子的作者信息(假设 likes 集合存储了 userIdpostId)。

2.2 实现

db.likes.aggregate([
{ $match: { userId: ObjectId("1234567890abcdef12345678") } },
{ $lookup: {
from: "posts",
localField: "postId",
foreignField: "_id",
as: "postInfo"
}},
{ $unwind: "$postInfo" },
{ $lookup: {
from: "users",
localField: "postInfo.authorId",
foreignField: "_id",
as: "authorInfo"
}},
{ $unwind: "$authorInfo" },
{ $project: {
_id: 0,
postTitle: "$postInfo.title",
authorName: "$authorInfo.name",
likedAt: "$createdAt"
}}
])
  1. 解释 $lookup 的原理,以及 MongoDB 为何不擅长 JOIN

  2. 询问 $unwind 在这个查询中的作用,以及 $lookup 结果是数组时如何处理?

  3. 让候选人优化该查询,例如添加索引、避免 $unwind 过多导致性能问题。

三、统计订单总数和订单金额平均值


3.1 认识

统计订单总数和订单金额平均值: 使用 $facet 进行并行统计, 同时返回 订单总数 和 订单金额平均值,而不是分两次查询数据库。

3.2 实现

db.orders.aggregate([
{ $facet: {
orderStats: [
{ $group: { _id: null, totalOrders: { $sum: 1 } } }
],
amountStats: [
{ $group: { _id: null, avgAmount: { $avg: "$orderAmount" } } }
]
}}
])