MongoDB聚合指南
管道阶段参考
| 阶段 | 用途 | 说明 |
|---|---|---|
| $match | 过滤文档(类似 WHERE) | 尽早放置以利用索引 |
| $group | 分组+累计(需要 _id) | $sum、$avg、$min、$max、$push |
| $project | 重塑输出字段 | 1=包含,0=排除,支持表达式 |
| $sort | 排序结果 | 1=升序,-1=降序 |
| $limit / $skip | 分页 | 大数据量时 $skip 性能差 |
| $lookup | 与其他集合左外连接 | 支持 pipeline 子查询 |
| $unwind | 将数组字段展开为多条文档 | preserveNullAndEmptyArrays 选项 |
| $addFields | 添加/覆盖字段 | 别名:$set |
| $facet | 单次扫描执行多个子管道 | 适合搜索+统计+分面查询 |
| $bucket | 按范围分组 | $bucketAuto 自动划分范围 |
常见聚合模式
// 销售报表:按类别和月份统计收入
db.orders.aggregate([
{ $match: { status: "completed", createdAt: { $gte: ISODate("2024-01-01") } } },
{ $unwind: "$items" },
{ $group: {
_id: { month: { $month: "$createdAt" }, category: "$items.category" },
revenue: { $sum: { $multiply: ["$items.price", "$items.qty"] } },
orderCount: { $sum: 1 }
}},
{ $sort: { "_id.month": 1, revenue: -1 } },
{ $project: {
_id: 0,
month: "$_id.month",
category: "$_id.category",
revenue: { $round: ["$revenue", 2] },
orderCount: 1
}}
]);
// $lookup 多条件连接
db.orders.aggregate([
{ $lookup: {
from: "products",
let: { productId: "$productId", minQty: "$quantity" },
pipeline: [
{ $match: { $expr: {
$and: [
{ $eq: ["$_id", "$$productId"] },
{ $gt: ["$stock", "$$minQty"] }
]
}}}
],
as: "productDetails"
}}
]);
// 分面搜索(结果+数量+价格区间一次完成)
db.products.aggregate([
{ $match: { $text: { $search: "笔记本" } } },
{ $facet: {
results: [{ $sort: { score: -1 } }, { $limit: 20 }],
totalCount: [{ $count: "count" }],
byBrand: [{ $group: { _id: "$brand", count: { $sum: 1 } } }],
priceRanges: [{ $bucket: {
groupBy: "$price",
boundaries: [0, 2000, 5000, 10000],
default: "10000以上",
output: { count: { $sum: 1 } }
}}]
}}
]);