我在mongodb中有下面的文档,其中等级键是一个包含对象和数组组合的数组。我的数据库里有几张这样的记录。我希望更新数组,并将其作为所有此类记录的对象。如何通过更新查询实现这一点?
{
_id: 4,
grades: [
{ grade: 80, mean: 75, std: 8 },
{ grade: 85, mean: 90, std: 5 },
[{ grade: 85, mean: 85, std: 8 }]
]
}
预期产出:
{
_id: 4,
grades: [
{ grade: 80, mean: 75, std: 8 },
{ grade: 85, mean: 90, std: 5 },
{ grade: 85, mean: 85, std: 8 }
]
}
发布于 2021-09-23 08:51:50
在MongoDB 3.4中使用单个更新查询无法做到这一点,
1)您可以在循环中执行2次查询(首先查找和第二次更新),可以在mongo或任何MongoDB编辑器中执行:
find()
查询for
循环grades
数组update()
数组的grades
查询db.getCollection('grades').find({}, { grades: 1 }).forEach(function (doc) {
var grades = [];
for(var i = 0; i < doc.grades.length; i++) {
if (Array.isArray(doc.grades[i])) {
grades = grades.concat(doc.grades[i]);
}
else {
grades.push(doc.grades[i]);
}
}
// update
db.getCollection('grades').update(
{ _id: doc._id },
{ $set: { grades: grades } }
)
})
2)您可以尝试使用单个查询在新集合中尝试聚合查询和导出更新的结果,
$reduce
迭代grades
数组的循环$type
$concatArrays
连接多个数组$cond
检查条件,然后将两个数组直接连接,否则将与数组连接到数组中。$out
导出新集合中的集合db.collection.aggregate([
{
$addFields: {
grades: {
$reduce: {
input: "$grades",
initialValue: [],
in: {
$cond: [
{ $eq: [{ $type: "$$this" }, "array"] },
{ $concatArrays: ["$$value", "$$this"] },
{ $concatArrays: ["$$value", ["$$this"]] }
]
}
}
}
}
},
{ $out: "collection name" }
])
3)在使用聚合管道进行更新 4.2上使用MongoDB query 的备用选项,
db.collection.updateMany({},
[{
$set: {
grades: {
$reduce: {
input: "$grades",
initialValue: [],
in: {
$cond: [
{ $eq: [{ $type: "$$this" }, "array"] },
{ $concatArrays: ["$$value", "$$this"] },
{ $concatArrays: ["$$value", ["$$this"]] }
]
}
}
}
}
}]
)
https://stackoverflow.com/questions/69303806
复制