I have many records in a MongoDB database, like this:
[
{
rootName: "AAA",
outerItem: {
innerItems: [
{
name: "A"
},
{
name: null
},
{
name: "C"
}
]
}
}
]
I would like to copy the rootName field of each record into an outerItem.innerItems[1].newField only, using a named index position of 1 (or looking up the correct index in some other way).
What I expect is for each record to look like this, after the code is run:
[
{
"rootName": "AAA",
"outerItem": {
"innerItems": [
{ // 0
"name": "A",
},
{ // 1
"name": null,
"newField": "AAA" // New item should be added here only (array index 1)
},
{ // 2
"name": "C",
}
]
}
}
]
I've tried using this code:
db.collection.update({},
[
{
"$set": {
"outerItem.innerItems": {
$map: {
input: "$outerItem.innerItems",
in: {
$mergeObjects: [
"$$this",
{
newField: "$rootName"
}
]
}
}
}
}
}
],
{
"multi": false,
"upsert": false
})
MongoDB Playground Link: https://mongoplayground.net/p/QhN1qAbWFwZ
But I end up with this:
[
{
"_id": ObjectId("5a934e000102030405000000"),
"outerItem": {
"innerItems": [
{
"name": "A",
"newField": "AAA"
},
{
"name": null,
"newField": "AAA"
},
{
"name": "C",
"newField": "AAA"
}
]
},
"rootName": "AAA"
}
]
The problem is that the newField is copied to all the array items, when I only want it copied to 1 specific array item of index 1.
I tried to modify the code to use a condition of array index 1, but the following code does not work. It produces an error:
db.collection.update({},
[
{
"$set": {
"outerItem.innerItems": {
$map: {
input: "$outerItem.innerItems",
in: {
$cond: [
{
$eq: [
"$$item.id",
1
]
}
],
$mergeObjects: [
"$$this",
{
newField: "$rootName"
}
]
}
}
}
}
}
],
{
"multi": false,
"upsert": false
})
MongoDB Playground link: https://mongoplayground.net/p/ckgDCUN1XrR
This version also doesn't work:
db.collection.update({
"outerItem.innerItems": {
$elemMatch: {
"name": null
}
}
},
[ ... ]
I can't figure out how to get it working. I have used the following guides so far, but I still cannot find a working solution for this scenario.
- Mongo updateMany statement with an inner array of objects to manipulate
- update one element of array of objects in mongodb
- Update array at specific index by other filed in MongoDB -- this example uses operators like
$concatArrayswith a$cond(condition) on the array - https://www.mongodb.com/docs/manual/reference/method/db.collection.updateMany/
- MongoDB: How do I update a single subelement in an array, referenced by the index within the array?
- https://www.mongodb.com/community/forums/t/how-can-we-assign-one-field-value-to-another/16396/4
- https://www.geeksforgeeks.org/how-to-update-mongodb-field-using-value-of-another-field/
How do I get it working? The final code is intended to be used in Node.js TypeScript code, probably using something like:
await queryRunner.updateMany('name_items', {}, [ { $set: ... } ] );
name: null" ?"name": null. By the way, thanks for your great answer. It's appreciated a lot, and I was impressed by how quickly you answered it.