$facet(多面聚合)
最后更新:2026-10-09
$facet(多面聚合)
$facet 在单个阶段内并行执行多个子管道,每个子管道独立处理同一份输入文档,结果以字段形式合并输出:{ 子管道名: 结果数组 }。适合一次请求同时拿到汇总统计、明细列表、Top N 等多个维度的结果,避免多次往返。子管道之间互不影响。
| 分类 | 分组与窗口 |
|---|---|
| MongoDB 版本 | 1.0+ |
| 示例语言 | mongosh (Shell) |
📝 语法
{ $facet: { <输出字段1>: [ <子管道1> ], <输出字段2>: [ <子管道2> ] } }
⚙️ 参数
| 子管道 | 字段名映射到子管道数组,各自独立处理输入文档。 |
|---|
返回值:单条文档,字段为各子管道的结果数组
▶ 示例
请在本地安装的 mongosh 中执行以下命令(需已启动 mongod):
// $facet:同时统计状态分布和金额 Top 5
db.orders.aggregate([
{ $facet: {
byStatus: [{ $group: { _id: '$status', n: { $sum: 1 } } }],
top5: [{ $sort: { amount: -1 } }, { $limit: 5 }]
} }
])
运行结果:
{ "byStatus": [ { "_id": "A", "n": 20 } ], "top5": [ { ... } ] }
📌 注意事项
- 子管道不能使用 $out、$merge、$facet 等不允许的阶段
- 子管道互不影响,各自处理 $facet 的完整输入
- 输出为单条文档,每个子管道名对应一个结果数组
🏷️ 相关标签
💡 相关案例
📚 相关教程
❓ 常见问题
Q$facet 里的子管道能排序吗?
A能,子管道里可以用 $sort、$limit 等普通阶段。
Q$facet 比多次 aggregate 调用快吗?
A通常更快,一次遍历完成多个聚合,减少 IO 和往返。
Q$facet 输出结构是什么?
A单条文档:每个子管道名对应一个结果数组。