MongoDB聚合:$addField

发布时间:2024年01月02日

本文主要介绍MongoDB聚合的$addField阶段的使用方法。

定义

为文档添加新字段,$addFields阶段输出文档包含了输入文档的全部字段和新增的字段。

$addFields阶段等价于$project阶段明确指定了输入文档的所有字段和新增字段。

注意:

MongoDB从4.2版本开始,增加了增加了一个新的阶段$set,是$addFields阶段的别名

语法

$addFields阶段的语法:

{ $addFields: { <newField>: <expression>, ... } }

指定所有新增字段的名称和值,值可以是表达式或空对象。

重点:

如果新字段的名称与已有字段的名称重复(包括_id),$addFields将使用指定表达式的值覆盖已有字段的值。

行为

  • $addFields阶段可以为文档增加一个或多个新字段。

  • $addFields阶段存在于聚合操作。

  • $addFields的值可以接受嵌套对象,也可以是聚合表达式或一个空对象,下面的内嵌对象是可接受的:

    {$addFields: { a: { b: { } } } }
    

    添加一个或多个字段到内嵌文档(数组文档)使用点符号。

  • $addFields$concatArrays可以为已有数组字段添加元素。

例子

使用两个$addFields阶段

集合scores包含以下文档:

{
  _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
}

下面的操作在$addFields阶段为输出文档增加三个字段:

db.scores.aggregate( [
   {
     $addFields: {
       totalHomework: { $sum: "$homework" } ,
       totalQuiz: { $sum: "$quiz" }
     }
   },
   {
     $addFields: { 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( [
        {
           $addFields: {
              "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" } }

覆盖已有字段

$addFields操作中指定重名字段会导致原字段被替换。

animals集合中包含如下文档:

{ _id: 1, dogs: 10, cats: 15 }

下面的$addFields操作指定了cats字段:

db.animals.aggregate( [
  {
    $addFields: { "cats": 20 }
  }
] )

操作后返回的文档如下:

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

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

fruit集合中包含了以下文档:

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

下面的$addFields聚合操作使用item字段替换了所有的_id字段的值,并用常量替换了item字段的值。

db.fruit.aggregate( [
  {
    $addFields: {
      _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 }
])

可以使用$addFields$concatArrays表达式为存在的数组字段添加元素。例如,下面的操作使用$addFieldshomework字段替换为一个新的数组,它的元素是当前homework数组与数组[-7]的并集。

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

操作结果:

{ "_id" : 1, "student" : "Maya", "homework" : [ 10, 5, 10, 7 ], "quiz" : [ 10, 8 ], "extraCredit" : 0 }
文章来源:https://blog.csdn.net/superatom01/article/details/135352056
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。