$documents是MongoDB在5.1版本中加入的聚合阶段,作用是把一组手写的文档直接作为聚合管道的输入,而不必依赖任何已存在的集合。它在db.aggregate()这种数据库级别的聚合调用中使用,也可以嵌入到$unionWith的pipeline里,为管道补充一份固定数据。对于经常需要调试聚合表达式、编写单元测试或构造演示数据的开发者来说,这个阶段能省去不少准备工作。

$documents的基本语法与使用位置
$documents的语法非常简单,它接受一个数组,数组中的每个元素就是一份文档。表达式通常配合数组字面量书写,例如[ { name: "A", score: 80 }, { name: "B", score: 95 } ]。要注意的是,$documents不能出现在db.collection.aggregate()的管道开头,因为集合聚合的第一个阶段已经有真实文档作为输入了。它的正确使用位置是db.aggregate(),这是数据库级别的聚合入口,管道没有默认输入,必须由第一个阶段提供数据。
下面是一个最基本的例子,直接传入三份文档并用$project做一次投影:
db.aggregate([
{
$documents: [
{ name: "张三", score: 80 },
{ name: "李四", score: 95 },
{ name: "王五", score: 60 }
]
},
{
$project: {
_id: 0,
name: 1,
grade: { $cond: [ { $gte: ["$score", 80] }, "优秀", "一般" ] }
}
}
])
执行后输出三条带grade字段的文档,整个过程没有涉及任何集合。这种写法非常适合快速验证$cond、$switch、$reduce等表达式的行为,改完参数立刻能看到结果,不用反复往测试集合里插数据再删数据。
与常用阶段配合的实战场景
$documents产生的文档流和普通阶段产生的没有区别,后续可以接$match、$group、$sort、$limit等任意阶段。比如想验证$group的分组统计逻辑,可以构造一批固定输入:
db.aggregate([
{
$documents: [
{ dept: "研发", salary: 20000 },
{ dept: "研发", salary: 25000 },
{ dept: "市场", salary: 15000 },
{ dept: "市场", salary: 18000 }
]
},
{
$group: {
_id: "$dept",
avgSalary: { $avg: "$salary" },
headcount: { $sum: 1 }
}
},
{ $sort: { avgSalary: -1 } }
])
另一个高频场景是配合$unionWith。当需要给已有集合的查询结果附加几条兜底记录或默认配置时,可以在$unionWith的子管道里用$documents提供这部分静态数据,例如给商品列表追加一条“暂无更多商品”的占位文档。相比维护一张只有几行数据的配置集合,这种方式不需要额外的存储和索引开销。
需要注意的限制有两点:第一,$documents传入的数据必须能被解析为文档数组,如果传入空数组,管道输出也为空,这是合法的;第二,$documents在数据库级别聚合中只能作为第一个阶段,如果放在其他位置会直接报错。此外,由于数据是内联在命令里的,单条命令有16MB的BSON限制,不适合塞入大规模数据。
调试、测试中的价值与常规聚合的取舍
在单元测试和脚本调试中,$documents的价值非常突出。假设你在开发一个复杂的报表聚合,管道有七八个阶段,如果每次都在真实集合上跑,数据会随环境变化,很难断言结果。改用$documents构造一组确定性输入,输出结果完全可预期,可以直接写入断言。配合驱动程序的测试框架,可以把整个管道逻辑做成独立于数据库状态的纯逻辑测试。
当然,$documents并不是替代常规聚合的方案。它没有索引、没有持久化,数据每次都要随命令传输,只适合数据量小、生命周期短的临时场景。一个简单的判断标准:如果输入数据需要反复查询、多端共享或者超过几千条,就应该落到真实集合里;如果只是验证表达式、构造演示样例或者附加少量静态数据,$documents是更轻便的选择。
常见报错方面,如果遇到“$documents is only valid as the first stage in db.aggregate”这类提示,说明你把该阶段放错了位置;如果报“$documents must be a non-empty array表达式错误”,检查数组元素是否都是合法的文档对象。掌握这些边界后,$documents会成为你调试MongoDB管道时非常趁手的小工具。
MongoDB$documents聚合管道修改时间:2026-09-09 21:12:46