Definition 定义

NOTE 歧义澄清: 下面的页面提到了 aggregation stage $set,从 MongoDB 4.2 开始可用,关于 update operator $set,参阅 $set

在文档中添加新的字段。$set 输出的文档包含输入文档中的所有现有字段新添加的字段

$set stage 是 $addFields 的一个别名。

这两个 stage 都等同于 $project stage,后者明确指定输入文档中的所有现有字段并添加新字段。

$set 的形式如下:

  1. { $set: { <newField>: <expression>, ... } }

指定要添加的每个字段的名称,并将其值设置为一个 aggregation expression。关于 expressions 的更多信息,参阅 Expressions

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

Behavior 行为

$set 将新的字段附加到现有的文档中。你可以在一个 aggregation operation 中包含一个或多个 $set stage。

要向嵌入式文档(包括数组中的文档)添加 field 或 fields,请使用点符号。请看例子

要用 $set 向一个现有的数组字段添加一个元素,请与 $concatArrays 一起使用。请看例子

Example 例子

Using Two $set Stages 使用两个 $set 阶段

创建一个 scorescollection,内容如下:

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

下面的 operation 使用了两个 $set stage,在输出文档中包含三个新的字段:

  1. db.scores.aggregate( [
  2. {
  3. $set: {
  4. totalHomework: { $sum: "$homework" },
  5. totalQuiz: { $sum: "$quiz" }
  6. }
  7. },
  8. {
  9. $set: {
  10. totalScore: { $add: [ "$totalHomework", "$totalQuiz", "$extraCredit" ] } }
  11. }
  12. ] )

该 operation 返回以下文档:

  1. {
  2. "_id" : 1,
  3. "student" : "Maya",
  4. "homework" : [ 10, 5, 10 ],
  5. "quiz" : [ 10, 8 ],
  6. "extraCredit" : 0,
  7. "totalHomework" : 25,
  8. "totalQuiz" : 18,
  9. "totalScore" : 43
  10. }
  11. {
  12. "_id" : 2,
  13. "student" : "Ryan",
  14. "homework" : [ 5, 6, 5 ],
  15. "quiz" : [ 8, 8 ],
  16. "extraCredit" : 8,
  17. "totalHomework" : 16,
  18. "totalQuiz" : 16,
  19. "totalScore" : 40
  20. }

Adding Fields to an Embedded Document 向嵌入式文档添加字段

使用点符号来添加新的字段到嵌入式文档。

用以下内容创建一个 vehicles collection:

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

下面的 aggregation operation 为嵌入式文档规范添加了一个新字段 fuel_type

  1. db.vehicles.aggregate( [
  2. { $set: { "specs.fuel_type": "unleaded" } }
  3. ] )

该 operation 返回以下文档:

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

Overwriting an existing field 覆盖现有字段

$set operation 中指定一个现有的字段名会导致原始字段被替换。

创建一个名为 animals的 collection,内容如下:

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

下面的 $set operation 覆盖了 cats 字段:

  1. db.animals.aggregate( [
  2. { $set: { "cats": 20 } }
  3. ] )

该 operation 返回以下内容:

  1. { _id: 1, dogs: 10, cats: 20 }

可以用一个字段替换另一个字段。在下面的例子中,item 字段替代了 _id 字段。

创建一个名为 fruits 的示例 collection,其中包含以下文档:

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

下面的 aggregation operation 使用 $set 将每个文档的 _id 字段替换为 item 字段的值,并将 item 字段替换为一个字符串 "fruit"

  1. db.fruits.aggregate( [
  2. { $set: { _id : "$item", item: "fruit" } }
  3. ] )

该 operation 返回以下内容:

  1. { "_id" : "tangerine", "item" : "fruit", "type" : "citrus" }
  2. { "_id" : "lemon", "item" : "fruit", "type" : "citrus" }
  3. { "_id" : "grapefruit", "item" : "fruit", "type" : "citrus" }

Add Element to an Array 向数组中添加元素

使用以下内容创建示例 scores collection:

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

您可以使用 $set$concatArrays expression 将元素添加到现有数组字段。 例如,以下 operation 使用 $sethomework 字段替换为新数组,其元素是当前 homework 数组与另一个包含新分数[ 7 ]连接。

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

该 operation 返回以下内容:

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

参考

https://docs.mongodb.com/manual/reference/operator/aggregation/set