文档菜单
文档首页
/
MongoDB 手册
/ / /

$addFields (聚合)

本页内容

  • 定义
  • 兼容性
  • 语法
  • 行为
  • 示例
$addFields

向文档中添加新字段。$addFields 输出包含输入文档中所有现有字段和新添加字段的文档。

关于$addFields 阶段相当于一个$project 阶段,该阶段明确指定输入文档中的所有现有字段并添加新字段。

注意

您还可以使用 $set 阶段,它是 $addFields 的别称。

您可以在以下环境中使用 $addFields

  • MongoDB Atlas:云中 MongoDB 部署的全托管服务

阶段具有以下语法

{ $addFields: { <newField>: <expression>, ... } }

指定要添加的字段名称并将其值设置为聚合表达式或空对象。有关表达式更多信息,请参阅表达式运算符。

重要

如果新字段的名称与现有字段名称(包括_id)相同,则$addFields会使用指定的表达式值覆盖该字段的现有值。

  • $addFields会将新字段追加到现有文档中。您可以在聚合操作中包含一个或多个$addFields阶段。

  • $addFields接受将对象嵌入其中,您可以将其值设置为聚合表达式或空对象。例如,以下嵌套对象是可接受的

    {$addFields: { a: { b: { } } } }

    要向嵌入文档(包括数组中的文档)添加字段,请使用点符号。请参阅示例。

  • 要使用$addFields向现有数组字段添加元素,请与$concatArrays一起使用。请参阅示例。

名为 scores 的集合包含以下文档

db.scores.insertMany( [
{
_id: 1,
student: "Maya",
homework: [ 10, 5, 10 ],
quiz: [ 10, 8 ],
extraCredit: 0
},
{
_id: 2,
student: "Ryan",
homework: [ 5, 6, 5 ],
quiz: [ 8, 8 ],
extraCredit: 8
}
] )

以下操作使用两个 $addFields 阶段将三个新字段包含在输出文档中

db.scores.aggregate( [
{
$addFields: {
totalHomework: { $sum: "$homework" } ,
totalQuiz: { $sum: "$quiz" }
}
},
{
$addFields: { totalScore:
{ $add: [ "$totalHomework", "$totalQuiz", "$extraCredit" ] } }
}
] )

操作返回以下文档

[
{
_id: 1,
student: "Maya",
homework: [ 10, 5, 10 ],
quiz: [ 10, 8 ],
extraCredit: 0,
totalHomework: 25,
totalQuiz: 18,
totalScore: 43
},
{
_id: 2,
student: "Ryan",
homework: [ 5, 6, 5 ],
quiz: [ 8, 8 ],
extraCredit: 8,
totalHomework: 16,
totalQuiz: 16,
totalScore: 40
}
]

使用点表示法向嵌套文档添加新字段。

例如,创建一个包含以下文档的名为 vehicles 的集合

db.vehicles.insertMany( [
{ _id: 1, type: "car", specs: { doors: 4, wheels: 4 } },
{ _id: 2, type: "motorcycle", specs: { doors: 0, wheels: 2 } },
{ _id: 3, type: "jet ski" }
] )

以下聚合操作向嵌套文档 specs 添加一个新字段 fuel_type

db.vehicles.aggregate( [
{ $addFields: { "specs.fuel_type": "unleaded" } }
] )

操作返回以下结果

[
{ _id: 1, type: "car",
specs: { doors: 4, wheels: 4, fuel_type: "unleaded" } },
{ _id: 2, type: "motorcycle",
specs: { doors: 0, wheels: 2, fuel_type: "unleaded" } },
{ _id: 3, type: "jet ski",
specs: { fuel_type: "unleaded" } }
]

$addFields操作中指定现有字段名称会导致原始字段被替换。

名为animals的集合包含以下文档

db.animals.insertOne(
{ _id: 1, dogs: 10, cats: 15 }
)

以下$addFields操作指定了cats字段。

db.animals.aggregate( [
{
$addFields: { cats: 20 }
}
] )

操作返回以下文档

[ { _id: 1, dogs: 10, cats: 20 } ]

可以替换一个字段为另一个字段。在以下示例中,item字段替换了_id字段。

名为fruit的集合包含以下文档

db.fruit.insertMany( [
{ _id: 1, item: "tangerine", type: "citrus" },
{ _id: 2, item: "lemon", type: "citrus" },
{ _id: 3, item: "grapefruit", type: "citrus" }
] )

以下聚合操作使用$addFields将每个文档的_id字段替换为item字段的值,并将item字段替换为一个静态值。

db.fruit.aggregate( [
{
$addFields: {
_id : "$item",
item: "fruit"
}
}
] )

操作返回以下内容

[
{ _id: "tangerine", item: "fruit", type: "citrus" },
{ _id: "lemon", item: "fruit", type: "citrus" },
{ _id: "grapefruit", item: "fruit", type: "citrus" }
]

创建一个名为scores的样本集合,如下所示

db.scores.insertMany( [
{ _id: 1, student: "Maya", homework: [ 10, 5, 10 ], quiz: [ 10, 8 ], extraCredit: 0 },
{ _id: 2, student: "Ryan", homework: [ 5, 6, 5 ], quiz: [ 8, 8 ], extraCredit: 8 }
] )

可以使用$addFields与一个$concatArrays表达式一起使用,向现有数组字段添加元素。例如,以下操作使用$addFieldshomework字段替换为一个新的数组,其元素是当前的homework数组与包含新分数[ 7 ]的数组的连接。

db.scores.aggregate( [
{ $match: { _id: 1 } },
{ $addFields: { homework: { $concatArrays: [ "$homework", [ 7 ] ] } } }
] )

操作返回以下内容

[ { _id: 1, student: "Maya", homework: [ 10, 5, 10, 7 ], quiz: [ 10, 8 ], extraCredit: 0 } ]

您可以使用$addFields$$REMOVE变量来删除文档字段。

例如,创建一个labReadings集合

db.labReadings.insertMany( [
{
date: ISODate("2024-10-09"),
temperature: 80
},
{
date: null,
temperature: 83
},
{
date: ISODate("2024-12-09"),
temperature: 85
}
] )

要从labReadings文档中删除date字段,请使用带有$$REMOVE变量的$addFields

db.labReadings.aggregate( [
{
$addFields: { date: "$$REMOVE" }
}
] )

输出

[
{ _id: ObjectId('671285306fd2c3b24f2e7eaa'), temperature: 80 },
{ _id: ObjectId('671285306fd2c3b24f2e7eab'), temperature: 83 },
{ _id: ObjectId('671285306fd2c3b24f2e7eac'), temperature: 85 }
]

您还可以使用$$REMOVE来有条件地删除字段。例如,以下聚合操作在datenull的文档中删除date字段

db.labReadings.aggregate( [
{
$addFields:
{
date: {
$ifNull: [ "$date", "$$REMOVE" ]
}
}
}
] )

输出

[
{
_id: ObjectId('671285306fd2c3b24f2e7eaa'),
date: ISODate('2024-10-09T00:00:00.000Z'),
temperature: 80
},
{ _id: ObjectId('671285306fd2c3b24f2e7eab'), temperature: 83 },
{
_id: ObjectId('671285306fd2c3b24f2e7eac'),
date: ISODate('2024-12-09T00:00:00.000Z'),
temperature: 85
}
]

提示

与$project比较

您可以使用$addFields$project阶段来删除文档字段。最佳方法取决于您的管道以及您希望保留原始文档的多少。

有关在$project阶段使用$$REMOVE的示例,请参阅有条件排除字段。

返回

阶段