$match 与 $project
本教程共 50 篇 · 第 29 篇 · 更新于 2026-07-30 · 约 7 分钟阅读
29. $match 与 $project
本节目标:掌握聚合里的 $match 过滤阶段和 $project 重塑阶段,能重命名字段、计算新字段、按需排除 _id,把输出整理成想要的模样。
$match 和 $project 是聚合管道上出场率最高的两个阶段:一个负责「留下哪些文档」,一个负责「每条长什么样」。
db.orders.insertMany([
{ _id: 1001, user_id: 1, status: "completed", total: 657 },
{ _id: 1002, user_id: 2, status: "completed", total: 1099 },
{ _id: 1003, user_id: 1, status: "shipped", total: 597 },
{ _id: 1004, user_id: 3, status: "pending", total: 528 }
])
$match:聚合里的过滤器
$match 的写法和 find 的筛选条件一模一样,支持所有查询运算符:
// 只保留 total 大于 600 的订单
db.orders.aggregate([
{ $match: { total: { $gt: 600 } } }
])
也可以组合多个条件:
// 已完成、且金额大于 600
db.orders.aggregate([
{ $match: { status: "completed", total: { $gt: 600 } } }
])
Note
$match能用到索引,尤其是写在管道第一位时。所以过滤条件尽量用$match表达,别留到后面用$project硬筛。
$project:重塑输出结构
$project 决定结果文档保留哪些字段、怎么改名、要不要算新字段。基础用法和 find 的投影很像:
// 只留 user_id 和 total,并去掉 _id
db.orders.aggregate([
{ $project: { _id: 0, user_id: 1, total: 1 } }
])
重命名字段
用一个表达式 "新名": "$旧名" 就能把字段改名。注意引用原字段值时,字段名前要加 $:
// 把 user_id 改名为 buyer,total 改名为 amount
db.orders.aggregate([
{ $project: { _id: 0, buyer: "$user_id", amount: "$total" } }
])
计算新字段
$project 里可以用聚合表达式对字段做计算。比如算含税金额(加 10%):
// 新增 amountWithTax 字段,等于 total 乘 1.1
db.orders.aggregate([
{
$project: {
_id: 0,
user_id: 1,
amountWithTax: { $multiply: ["$total", 1.1] }
}
}
])
Tip表达式里引用原字段必须写
"$total"(带美元符),字面量直接写数字即可。运算符如$multiply接收数组参数。
同时保留、改名与计算
一个 $project 里可以混用保留、改名、算新字段:
db.orders.aggregate([
{
$project: {
_id: 0,
buyer: "$user_id", // 改名
amount: "$total", // 改名
amountWithTax: { $multiply: ["$total", 1.1] } // 计算
}
}
])
用 $project 也能「过滤掉」某些文档
如果某个字段是数组或子文档,你还能在 $project 里用 $filter、$slice 等表达式进一步裁剪。这属于进阶用法,记住 $project 不只是「选列」,更是「改形」。
Warning
$project出现在管道中间时,没列出的字段会被丢弃,后续阶段就访问不到了。需要后续阶段用到的字段,要么保留,要么先$addFields追加(不丢原字段)。
两阶段配合示例
先过滤已完成订单,再输出精简后的「买家 + 金额 + 含税」结构:
db.orders.aggregate([
{ $match: { status: "completed" } },
{
$project: {
_id: 0,
buyer: "$user_id",
amount: "$total",
amountWithTax: { $multiply: ["$total", 1.1] }
}
}
])
$match 和 $project 配合,是绝大多数聚合管道的开头两板斧。下一章看分组统计的核心:$group 与各类累加器。