聚合管道入门
约 467 字大约 2 分钟
布欧-Lewyon
2026-05-15
首页 › MongoDB › 索引与聚合(在新窗口打开) › 聚合管道入门
聚合管道概念
聚合管道(Aggregation Pipeline)将文档通过多个阶段进行处理和转换。
db.orders.aggregate([
{ $match: { status: "completed" } }, // 阶段 1:过滤
{ $group: { _id: "$category", total: { $sum: "$amount" } } }, // 阶段 2:分组
{ $sort: { total: -1 } }, // 阶段 3:排序
{ $limit: 5 } // 阶段 4:取前 5
])$match
过滤文档(类似 find 的查询条件):
db.orders.aggregate([
{ $match: { status: "completed", amount: { $gte: 100 } } }
])
$match尽量放在管道最前面,可以利用索引。
$group
分组聚合:
// 按分类统计订单数和总金额
db.orders.aggregate([
{ $group: {
_id: "$category", // 分组字段
count: { $sum: 1 }, // 每个组的文档数
totalAmount: { $sum: "$amount" }, // 金额总和
avgAmount: { $avg: "$amount" }, // 金额平均值
minAmount: { $min: "$amount" }, // 最小值
maxAmount: { $max: "$amount" } // 最大值
}}
])
// 复杂分组:按年 + 按分类
db.orders.aggregate([
{ $group: {
_id: {
year: { $year: "$createdAt" },
category: "$category"
},
total: { $sum: "$amount" }
}}
])$project
选择/重命名/计算字段:
db.orders.aggregate([
{ $project: {
_id: 0,
orderId: "$_id",
total: 1,
tax: { $multiply: ["$amount", 0.1] },
year: { $year: "$createdAt" },
fullName: { $concat: ["$firstName", " ", "$lastName"] }
}}
])$sort / $limit / $skip
db.orders.aggregate([
{ $sort: { amount: -1 } },
{ $skip: 10 }, // 分页
{ $limit: 10 }
])完整示例
// 统计每个用户每月消费总额,取前 10 名
db.orders.aggregate([
{ $match: { status: "completed" } },
{ $group: {
_id: {
userId: "$userId",
month: { $dateToString: { format: "%Y-%m", date: "$createdAt" } }
},
totalSpent: { $sum: "$amount" },
orderCount: { $sum: 1 }
}},
{ $sort: { totalSpent: -1 } },
{ $limit: 10 },
{ $project: {
_id: 0,
userId: "$_id.userId",
month: "$_id.month",
totalSpent: 1,
orderCount: 1
}}
])小结
- 聚合管道是数据处理的核心,由多个阶段组成,数据依次通过每个阶段。
$match过滤(尽量前置以利用索引)、$group分组聚合、$project投射。$sort、$limit、$skip排序和分页。$sum/$avg/$min/$max在$group中做聚合计算。$year/$dateToString处理日期字段。
上一节:explain 与查询优化 下一节:聚合管道进阶
