聚合$set
阶段可以为文档添加新的字段。$set
输出的文档包含输入文档中的所有现有字段和新添加的字段。$set
是$addFields
的别名,从MongoDB4.2开始支持。$set
和$addFields
等价于$project
阶段,这两个阶段都等同于 $project 阶段,后者明确指定输入文档中的所有现有字段并添加新字段。
{ $set: { <newField>: <expression>, ... } }
指定要添加的每个字段的名称,并将其值设置为聚合表达式或空对象。
如果新字段的名称与现有字段的名称(包括 _id)相同,$set
将用指定表达式的值覆盖该字段的现有值。
$set
阶段。{$set:{ a:{ b: { }}}}
$set
阶段创建一个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 }
])
以下操作使用了两个$set
阶段,在输出文档中加入三个新字段:
db.scores.aggregate( [
{
$set: {
totalHomework: { $sum: "$homework" },
totalQuiz: { $sum: "$quiz" }
}
},
{
$set: {
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( [
{ $set: { "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" } }
在$set
操作中指定一个已存在的字段,原有字段会被替换。创建一个animals
集合:
db.animals.insertOne( { _id: 1, dogs: 10, cats: 15 } )
下面的$set
聚合操作覆盖了cats
字段:
db.animals.aggregate( [
{ $set: { "cats": 20 } }
] )
操作返回以下文件:
{ _id: 1, dogs: 10, cats: 20 }
可以用一个字段替换另一个字段。在下面的示例中,item
字段替代了_id
字段。创建一个名为fruits
的样本集合,其中包含以下文档:
db.fruits.insertMany([
{ "_id" : 1, "item" : "tangerine", "type" : "citrus" },
{ "_id" : 2, "item" : "lemon", "type" : "citrus" },
{ "_id" : 3, "item" : "grapefruit", "type" : "citrus" }
])
下面的聚合操作使用$set
将每个文档的_id
字段替换为item
字段的值,并将item
字段替换为字符串"fruit"。
db.fruits.aggregate( [
{ $set: { _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 }
])
可以使用$set
与$concatArrays
表达式配合使用,可向现有数组字段添加元素。例如,以下操作使用$set
将homework
字段替换为一个新数组,新数组的元素是homework
数组与数组[7]
元素合并后的结果。
db.scores.aggregate([
{ $match: { _id: 1 } },
{ $set: { homework: { $concatArrays: [ "$homework", [ 7 ] ] } } }
])
该操作的返回值如下:
{ "_id" : 1, "student" : "Maya", "homework" : [ 10, 5, 10, 7 ], "quiz" : [ 10, 8 ], "extraCredit" : 0 }
创建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 }
])
下面的聚合操作为每个文档添加了一个新字段quizAverage
,其中包含quiz
数组的平均值。
db.scores.aggregate( [
{
$set: {
quizAverage: { $avg: "$quiz" }
}
}
] )
db.scores.aggregate( [
{
$set: {
quizAverage: { $avg: "$quiz" }
}
}
] )
该操作返回如下文档:
[
{
_id: 1,
student: 'Maya',
homework: [ 10, 5, 10 ],
quiz: [ 10, 8 ],
extraCredit: 0,
quizAverage: 9
},
{
_id: 2,
student: 'Ryan',
homework: [ 5, 6, 5 ],
quiz: [ 8, 8 ],
extraCredit: 8,
quizAverage: 8
}
]