面试题答案
一键面试在MongoDB中,可以使用以下更新操作语句:
db.documents.updateOne(
{},
[
{
$addFields: {
scores: {
$map: {
input: "$scores",
as: "score",
in: {
$cond: [
{ $eq: ["$$score.subject", "Math"] },
{ subject: "Math", score: { $add: ["$$score.score", 5] } },
"$$score"
]
}
}
}
}
},
{
$addFields: {
scores: {
$cond: [
{ $not: { $in: ["History", "$scores.subject"] } },
{
$concatArrays: ["$scores", [ { subject: "History", score: 0 } ] ]
},
"$scores"
]
}
}
}
],
{ multi: true }
);
操作符原理解释:
- $addFields:用于向文档中添加新的字段或替换现有字段的值。这里使用了两次
$addFields
操作符,分别对scores
数组进行修改。 - $map:对数组的每个元素应用指定的表达式,并返回新的数组。在第一个
$addFields
中,$map
遍历scores
数组,检查每个元素的subject
是否为Math
。如果是,则将该元素的score
增加5分;否则,保持该元素不变。 - $cond:条件操作符,根据条件表达式的值返回不同的结果。在
$map
中,$cond
用于判断当前score
的subject
是否为Math
,并根据结果返回修改后的score
或原始score
。在第二个$addFields
中,$cond
用于判断History
是否在scores
数组的subject
中。如果不在,则将{ subject: "History", score: 0 }
添加到scores
数组中;否则,保持scores
数组不变。 - $concatArrays:用于连接多个数组。在第二个
$addFields
中,当History
不在scores
数组的subject
中时,$concatArrays
将原scores
数组和[ { subject: "History", score: 0 } ]
连接起来,形成新的scores
数组。 - $not:逻辑操作符,对表达式的结果取反。在第二个
$addFields
中,$not
用于判断History
不在scores
数组的subject
中。 - $in:检查一个值是否在数组中。在第二个
$addFields
中,$in
用于检查History
是否在scores
数组的subject
中。
最后,{ multi: true }
选项确保对集合中的所有文档执行更新操作。如果不设置该选项,默认只更新第一个匹配的文档。