$set (聚合)
定义
$set
向文档中添加新字段。
$set
输出包含输入文档中所有现有字段和新添加字段的文档。聚合阶段
$set
是$addFields
的别名。这两个阶段等同于一个显式指定输入文档中所有现有字段并添加新字段的
$project
阶段。
兼容性
您可以使用 $set
对以下环境中的部署进行操作
MongoDB Atlas:云中MongoDB部署的全托管服务
MongoDB Enterprise:基于订阅的自托管MongoDB版本
MongoDB Community:开源的、免费使用并自托管的MongoDB版本
语法
$set
有以下形式
{ $set: { <newField>: <expression>, ... } }
指定要添加的每个字段的名称并将其值设置为聚合表达式或空对象。有关表达式更多信息,请参阅 表达式运算符。
重要
如果新字段的名称与现有字段名称相同(包括 _id
),$set
将覆盖该字段的现有值,使用指定的表达式值。
行为
$set
向现有文档中添加新字段。您可以在聚合操作中包含一个或多个$set
阶段。$set
接受嵌入对象,您可以将其设置为一个聚合表达式或一个空对象。例如,以下嵌套对象是被接受的{$set: { a: { b: { } } } } 要向嵌入的文档(包括数组中的文档)添加字段或字段,请使用点表示法。请参阅 示例。
要使用
$set
向现有的数组字段添加元素,请使用$concatArrays
。请参阅 示例。
示例
使用两个 $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 } ] )
以下聚合操作向包含 quiz
数组平均值的每个文档添加了一个新字段 quizAverage
。
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 } ]