Reputation: 2097
I have the below document in mongodb, where grades key is an array with the combination of objects and array. I have several records like this in my db. i wanted to update the array and have it as an object for all such records. How can i achieve this with update query ?
{
_id: 4,
grades: [
{ grade: 80, mean: 75, std: 8 },
{ grade: 85, mean: 90, std: 5 },
[{ grade: 85, mean: 85, std: 8 }]
]
}
Expected output :
{
_id: 4,
grades: [
{ grade: 80, mean: 75, std: 8 },
{ grade: 85, mean: 90, std: 5 },
{ grade: 85, mean: 85, std: 8 }
]
}
Upvotes: 1
Views: 180
Reputation: 36114
It is not possible to do this using single update query in MongoDB 3.4,
find()
query to project require field and loop the resultfor
loop the grades
arrayupdate()
query to update new grades
arraydb.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 } }
)
})
$reduce
to iterate loop of grades
array$type
to get data type of the element$concatArrays
to concat multiple arrays$cond
check condition if element type is array then concat directly both arrays otherwise concat with array into array$out
to export collection in new collectiondb.collection.aggregate([
{
$addFields: {
grades: {
$reduce: {
input: "$grades",
initialValue: [],
in: {
$cond: [
{ $eq: [{ $type: "$$this" }, "array"] },
{ $concatArrays: ["$$value", "$$this"] },
{ $concatArrays: ["$$value", ["$$this"]] }
]
}
}
}
}
},
{ $out: "collection name" }
])
db.collection.updateMany({},
[{
$set: {
grades: {
$reduce: {
input: "$grades",
initialValue: [],
in: {
$cond: [
{ $eq: [{ $type: "$$this" }, "array"] },
{ $concatArrays: ["$$value", "$$this"] },
{ $concatArrays: ["$$value", ["$$this"]] }
]
}
}
}
}
}]
)
Upvotes: 1