Reputation: 53
I am trying to update data in my MongoDB (4.2) by using update with a pipeline. The difficulty is that I want to add a field to an array element depending on another field. Also I want to do this for each element. I know I could do by Javascript for each but I was wondering if there is a better way. So this is what I want to do as an example
Before:
{
"_id" : ObjectId("555555555"),
"messages" : [
{
"author" : {
"userId" : "12345",
"name" : "John"
},
"text" : "Any text",
},
{
"author" : {
"userId" : "56789",
"name" : "Jim"
},
"text" : "also text"
}
]
}
After
{
"_id" : ObjectId("555555555"),
"messages" : [
{
"author" : {
"userId" : "12345",
"name" : "John",
"newId" : "00012345"
},
"text" : "Any text",
},
{
"author" : {
"userId" : "56789",
"name" : "Jim",
"newId" : "00056789"
},
"text" : "also text"
}
]
}
What I tried:
db.mail.update(
{"_id" : ObjectId("555555555")},
[{ $set: { "messages.$[].author.newId": { $concat: [ "000", "$messages.$[].author.userId"]}}}],
{ multi: true, writeConcern: {w: 0} }
)
Does anybody know how to solve this? Thank you
Upvotes: 3
Views: 772
Reputation: 14287
This will do the required update.
db.test.update(
{ _id : ObjectId("555555555") },
[
{
$set: {
messages: {
$map: {
input: "$messages",
in: {
$mergeObjects: [
"$$this",
{ "author": {
$mergeObjects: [
"$$this.author",
{ newId: { $concat: [ "000", "$$this.author.userId"] } }
]
} }
]
}
}
}
}
}
],
{ multi: true, writeConcern: {w: 0} }
)
Note that the all positional operator $[]
for array updates is to be used with update operations when not using the aggregation. You have to use aggregation to update when a field value depends upon another field in the document.
Upvotes: 3