本文主要介绍MongoDB聚合的$addField阶段的使用方法。
定义
为文档添加新字段,$addFields阶段输出文档包含了输入文档的全部字段和新增的字段。
$addFields阶段等价于$project阶段明确指定了输入文档的所有字段和新增字段。
注意:
MongoDB从4.2版本开始,增加了增加了一个新的阶段$set,是$addFields阶段的别名
语法
$addFields阶段的语法:
{ $addFields: {
指定所有新增字段的名称和值,值可以是表达式或空对象。
重点:
如果新字段的名称与已有字段的名称重复(包括_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表达式为存在的数组字段添加元素。例如,下面的操作使用$addFields把homework字段替换为一个新的数组,它的元素是当前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 }
推荐链接
发表评论