聚合管道更新

从MongoDB 4.2开始,您可以将聚合管道用于更新操作。 通过更新操作,聚合管道可以包括以下阶段:

使用聚合管道允许使用表达性更强的update语句,比如根据当前字段值表示条件更新,或者使用另一个字段的值更新一个字段。

例1

创建一个示例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") }
])

要验证,请查询集合:

db.students.find()

以下db.collection.updateOne()操作使用聚合管道使用**_id**更新文档:3

db.students.updateOne( { _id: 3 }, [ { $set: { "test3": 98, modified: "$$NOW"} } ] )

具体地说,管道包括$set阶段,该阶段将test3字段(并将其值设置为98)添加到文档中,并将修改后的字段设置为当前日期时间。 对于当前日期时间,该操作将聚合变量NOW 用于(以访问变量,以**$$**为前缀并用引号引起来)。

要验证更新,您可以查询集合:

例2

创建一个示例students2集合(如果该集合当前不存在,则插入操作将创建该集合):

要验证,请查询集合:

以下db.collection.updateMany() 操作使用聚合管道来标准化文档的字段(即,集合中的文档应具有相同的字段)并更新修改后的字段:

具体来说,管道包括:

  • $replaceRoot 阶段,带有 $mergeObjects表达式,可为quiz1quiz2test1test2字段设置默认值。 聚集变量ROOT 指的是正在修改的当前文档(以访问变量,以**$$**为前缀并用引号引起来)。 当前文档字段将覆盖默认值。

  • $set 阶段用于将修改的字段更新到当前日期时间。 对于当前日期时间,该操作将聚合变量NOW用于(以访问变量,以**$$**为前缀并用引号引起来)。

要验证更新,您可以查询集合:

例3

创建一个示例students3集合(如果该集合当前不存在,则插入操作将创建该集合):

要验证,请查询集合:

以下 db.collection.updateMany()操作使用聚合管道以计算的平均成绩和字母成绩更新文档。

具体来说,管道包括:

  • $set阶段来计算测试数组元素的截断平均值,并将修改后的字段更新为当前日期时间。 要计算截断的平均值,此阶段使用**$avg$trunc 表达式。 对于当前日期时间,该操作将聚合变量NOW 用于(以访问变量,以$$**为前缀并用引号引起来).

  • 一个$set 阶段,用于使用$switch 表达式根据平均值添加年级字段。

    要验证更新,您可以查询集合:

例4

创建一个示例students4集合(如果该集合当前不存在,则插入操作将创建该集合):

要验证,请查询集合:

以下db.collection.updateOne()操作使用聚合管道将测验分数添加到具有**_id**的文档中:2

要验证,请查询集合:

例5

创建一个示例temperatures集合,其中包含摄氏温度(如果该集合当前不存在,则插入操作将创建该集合):

要验证,请查询集合:

以下db.collection.updateMany()操作使用聚合管道以华氏度中的相应温度更新文档:

具体来说,管道由$addFields阶段组成,以添加一个新的数组字段tempsF,其中包含华氏温度。 要将tempsC数组中的每个摄氏温度转换为华氏温度,该阶段将$map表达式与$add$multiply表达式一起使用。

要验证更新,您可以查询集合:

其他例子

有关其他示例,另请参见各种更新方法页面:

译者:杨帅

校对:杨帅

最后更新于