Please consider the following data:
{
"_id": "F9F39JQH",
"field": {
"array": [
{
"itemId": 1
},
{
"itemId": 2
}
]
}
}
I’m trying to add a single field inside the first element or the array
.
{
"_id": "F9F39JQH",
"field": {
"array": [
{
"itemId": 1,
"newField": "val" <- add this field & value.
},
{
"itemId": 2
}
]
}
}
I tried executing either of the following pipeline updates:
const pipelineUpdate = [
{ $addFields: { "field.array.0": { newField: "val" } } }
];
const pipelineUpdate2 = [
{ $addFields: { "field.array.0.newField": "val" } }
];
db.users.updateOne({ _id: "F9F39JQH" }, pipelineUpdate);
But the result is quite unexpected:
{
"_id": "F9F39JQH",
"field": {
"array": [
{
"0": {
"newField": "val"
},
"itemId": 1
},
{
"0": {
"newField": "val"
},
"itemId": 2
}
]
}
}
$addFields
creates a field "0" in all array elements instead of using the ".0" as path selector to identify the target.
The documentation states: To add a field or fields to embedded documents (including documents in arrays) use the dot notation
However I found it not to be the case here. What am I missing ?
I specifically need to add fields inside an existing object of unknown structure. I cannot re-write the whole element using $set for example.
2
Answers
You may update the first element of the array via the aggregation pipeline.
Set the
field.array
value with:Get the first element of the
field.array
array and add thenewField
field.Get all the elements other than the first element of the
field.array
array.Combine the result of (1) and (2) into an array.
Demo @ Mongo Playground
Note that if you are using the MongoDB version 5.2 and above, you may consider replacing the
$slice
operator with$lastN
.Note that you don’t need to update with aggregation pipeline. You need the
$set
operator with dot notation.Here is the working live example:
https://mongoplayground.net/p/283qGaCzhFYData:
Aggregation:
Output: