Starting in MongoDB 4.2, you can use the aggregation pipeline for update operations. 从MongoDB 4.2开始,您可以使用聚合管道进行更新操作。With the update operations, the aggregation pipeline can consist of the following stages:通过更新操作,聚合管道可以由以下阶段组成:
Using the aggregation pipeline allows for a more expressive update statement, such as expressing conditional updates based on current field values or updating one field using the value of another field(s).使用聚合管道允许更具表现力的更新语句,例如基于当前字段值表达条件更新,或使用另一个字段的值更新一个字段。
You can try out the example in the provided shell. Click inside the shell to connect. 您可以在提供的shell中尝试该示例。在外壳内部单击以进行连接。Once connected, you can run the examples in the shell.连接后,您可以在shell中运行示例。
Create an example 创建示例students
collection (if the collection does not currently exist, insert operations will create the collection):students
集合(如果该集合当前不存在,则插入操作将创建该集合):
db.students.insertMany( [ { _id: 1, test1: 95, test2: 92, test3: 90, modified: new Date("01/05/2020") }, { _id: 2, test1: 98, test2: 100, test3: 102, modified: new Date("01/05/2020") }, { _id: 3, test1: 95, test2: 110, modified: new Date("01/04/2020") } ] )
To verify, query the collection:要验证,请查询集合:
db.students.find()
The following 以下db.collection.updateOne()
operation uses an aggregation pipeline to update the document with _id: 3
:db.collection.updateOne()
操作使用聚合管道更新_id
为3的文档:
db.students.updateOne( { _id: 3 }, [ { $set: { "test3": 98, modified: "$$NOW"} } ] )
Specifically, the pipeline consists of a 具体来说,管道由$set
stage which adds the test3
field (and sets its value to 98
) to the document and sets the modified
field to the current datetime. $set
阶段组成,它将test3
字段(并将其值设置为98)添加到文档中,并将modified
字段设置为当前日期时间。The operation uses the aggregation variable 操作将聚合变量NOW
for the current datetime. NOW
用于当前日期时间。To access the variable, prefix with 要访问变量,请以$$
and enclose in quotes.$$
作为前缀并用引号括起来。
To verify the update, you can query the collection:要验证更新,可以查询集合:
db.students.find().pretty()
You can try out the example in the provided shell. Click inside the shell to connect. 您可以在提供的shell中尝试该示例。在外壳内部单击以进行连接。Once connected, you can run the examples in the shell.连接后,您可以在shell中运行示例。
Create an example 创建示例students2
collection (if the collection does not currently exist, insert operations will create the collection):students2
集合(如果该集合当前不存在,则插入操作将创建该集合):
db.students2.insertMany( [ { "_id" : 1, quiz1: 8, test2: 100, quiz2: 9, modified: new Date("01/05/2020") }, { "_id" : 2, quiz2: 5, test1: 80, test2: 89, modified: new Date("01/05/2020") }, ] )
To verify, query the collection:要验证,请查询集合:
db.students2.find()
The following 以下db.collection.updateMany()
operation uses an aggregation pipeline to standardize the fields for the documents (i.e. db.collection.updateMany()
操作使用聚合管道来标准化文档的字段(即。documents in the collection should have the same fields) and update the 集合中的文档应具有相同的字段),并更新modified
field:modified
字段:
db.students2.updateMany( {}, [ { $replaceRoot: { newRoot: { $mergeObjects: [ { quiz1: 0, quiz2: 0, test1: 0, test2: 0 }, "$$ROOT" ] } } }, { $set: { modified: "$$NOW"} } ] )
Specifically, the pipeline consists of:具体而言,管道包括:
$replaceRoot
stage with a $mergeObjects
expression to set default values for the quiz1
, quiz2
, test1
and test2
fields. $replaceRoot
阶段,带有$mergeObjects
表达式,用于设置quiz1
、quiz2
、test1
和test2
字段的默认值。ROOT
refers to the current document being modified. ROOT
指正在修改的当前文档。$$
and enclose in quotes. $$
作为前缀并用引号括起来。$set
stage to update the modified
field to the current datetime. $set
阶段,用于将modified
字段更新为当前日期时间。NOW
for the current datetime. NOW
用于当前日期时间。$$
and enclose in quotes.$$
作为前缀并用引号括起来。To verify the update, you can query the collection:要验证更新,可以查询集合:
db.students2.find()
You can try out the example in the provided shell. 您可以在提供的shell中尝试该示例。Click inside the shell to connect. 在外壳内部单击以进行连接。Once connected, you can run the examples in the shell.连接后,您可以在shell中运行示例。
Create an example 创建示例students3
collection (if the collection does not currently exist, insert operations will create the collection):students3
集合(如果该集合当前不存在,则插入操作将创建该集合):
db.students3.insertMany( [ { "_id" : 1, "tests" : [ 95, 92, 90 ], "modified" : ISODate("2019-01-01T00:00:00Z") }, { "_id" : 2, "tests" : [ 94, 88, 90 ], "modified" : ISODate("2019-01-01T00:00:00Z") }, { "_id" : 3, "tests" : [ 70, 75, 82 ], "modified" : ISODate("2019-01-01T00:00:00Z") } ] );
To verify, query the collection:要验证,请查询集合:
db.students3.find()
The following 以下db.collection.updateMany()
operation uses an aggregation pipeline to update the documents with the calculated grade average and letter grade.db.collection.updateMany()
操作使用聚合管道使用计算出的等级平均值和字母等级更新文档。
db.students3.updateMany( { }, [ { $set: { average : { $trunc: [ { $avg: "$tests" }, 0 ] }, modified: "$$NOW" } }, { $set: { grade: { $switch: { branches: [ { case: { $gte: [ "$average", 90 ] }, then: "A" }, { case: { $gte: [ "$average", 80 ] }, then: "B" }, { case: { $gte: [ "$average", 70 ] }, then: "C" }, { case: { $gte: [ "$average", 60 ] }, then: "D" } ], default: "F" } } } } ] )
Specifically, the pipeline consists of:具体而言,管道包括:
$set
stage to calculate the truncated average value of the tests
array elements and to update the modified
field to the current datetime. $set
阶段,用于计算测试数组元素的截断平均值,并将modified
字段更新为当前日期时间。$avg
and $trunc
expressions. $avg
和$trunc
表达式。NOW
for the current datetime. NOW
用于当前日期时间。$$
and enclose in quotes.$$
作为前缀并用引号括起来。$set
stage to add the grade
field based on the average
using the $switch
expression.$set
阶段,用于使用$switch
表达式基于average
添加grade
字段。To verify the update, you can query the collection:要验证更新,可以查询集合:
db.students3.find()
You can try out the example in the provided shell. Click inside the shell to connect. 您可以在提供的shell中尝试该示例。在外壳内部单击以进行连接。Once connected, you can run the examples in the shell.连接后,您可以在shell中运行示例。
Create an example 创建示例students4
collection (if the collection does not currently exist, insert operations will create the collection):students4
集合(如果该集合当前不存在,则插入操作将创建该集合):
db.students4.insertMany( [ { "_id" : 1, "quizzes" : [ 4, 6, 7 ] }, { "_id" : 2, "quizzes" : [ 5 ] }, { "_id" : 3, "quizzes" : [ 10, 10, 10 ] } ] )
To verify, query the collection:要验证,请查询集合:
db.students4.find()
The following 以下db.collection.updateOne()
operation uses an aggregation pipeline to add quiz scores to the document with _id:
2
:db.collection.updateOne()
操作使用聚合管道将测验分数添加到_id
为2的文档中:
db.students4.updateOne( { _id: 2 }, [ { $set: { quizzes: { $concatArrays: [ "$quizzes", [ 8, 6 ] ] } } } ] )
To verify the update, query the collection:要验证更新,请查询集合:
db.students4.find()
You can try out the example in the provided shell. Click inside the shell to connect. 您可以在提供的shell中尝试该示例。在外壳内部单击以进行连接。Once connected, you can run the examples in the shell.连接后,您可以在shell中运行示例。
Create an example 创建包含摄氏温度的示例temperatures
collection that contains temperatures in Celsius (if the collection does not currently exist, insert operations will create the collection):temperatures
集合(如果该集合当前不存在,则插入操作将创建该集合):
db.temperatures.insertMany( [ { "_id" : 1, "date" : ISODate("2019-06-23"), "tempsC" : [ 4, 12, 17 ] }, { "_id" : 2, "date" : ISODate("2019-07-07"), "tempsC" : [ 14, 24, 11 ] }, { "_id" : 3, "date" : ISODate("2019-10-30"), "tempsC" : [ 18, 6, 8 ] } ] )
To verify, query the collection:要验证,请查询集合:
db.temperatures.find()
The following 以下db.collection.updateMany()
operation uses an aggregation pipeline to update the documents with the corresponding temperatures in Fahrenheit:db.collection.updateMany()
操作使用聚合管道以相应的华氏温度更新文档:
db.temperatures.updateMany( { }, [ { $addFields: { "tempsF": { $map: { input: "$tempsC", as: "celsius", in: { $add: [ { $multiply: ["$$celsius", 9/5 ] }, 32 ] } } } } } ] )
Specifically, the pipeline consists of an 具体来说,管道由一个$addFields
stage to add a new array field tempsF
that contains the temperatures in Fahrenheit. $addFields
阶段组成,用于添加一个新的数组字段tempsF
,该字段包含华氏温度。To convert each celsius temperature in the 为了将tempsC
array to Fahrenheit, the stage uses the $map
expression with $add
and $multiply
expressions.tempsC
数组中的每个摄氏温度转换为华氏温度,该阶段使用$map
表达式和$add
和$multiply
表达式。
To verify the update, you can query the collection:要验证更新,可以查询集合:
db.temperatures.find()
See also the various update method pages for additional examples:有关其他示例,请参阅各种更新方法页面: