I have these 2 documents. I need to update the "booksBought" arrays of the 2 documents at the same time with updateMany / update of MongoDB.
Here's the scenario: My query as of now is I select both users Josh and Carl with $in, then increment the quantity of a specific booktitle, in this example "harry potter". I filter the object using the [$] identifier and the arrayFilter condition to select the object. However, the other user isn't included in the filter since he doesn't have an object with "harry potter" in it.
How do I push it on the other user's "booksBought" array if the object doesn't exist although the user is part of the selection under $in?
Query
db.collection.update({
"userId": {
$in: [
"10000001",
"10000002"
]
}
},
{
$inc: {
"booksBought.$[elem].quantity": 10
}
},
{
arrayFilters: [
{
"elem.booktitle": "harry potter"
}
]
})
Document
[
{
"userId": "10000001",
"name": "Josh",
"booksBought": [
{
"booktitle": "harry potter",
"quantity": 1
},
{
"booktitle": "game of thrones",
"quantity": 2
}
]
},
{
"userId": "10000002",
"name": "Carl",
"booksBought": [
{
"booktitle": "lord of the rings",
"quantity": 4
}
]
}
]
Expected
[
{
"userId": "10000001",
"name": "Josh",
"booksBought": [
{
"booktitle": "harry potter",
"quantity": 11
},
{
"booktitle": "game of thrones",
"quantity": 2
}
]
},
{
"userId": "10000002",
"name": "Carl",
"booksBought": [
{
"booktitle": "lord of the rings",
"quantity": 4
},
{
"booktitle": "harry potter",
"quantity": 10
}
]
}
]
Playground link: https://mongoplayground.net/p/Aby5lhRckJT
Using update with aggregation pipeline, you can always pad the harry potter entry with 0 quantity first. Then, use $map
to iterate through the array and $add
10 to the quantity.
db.collection.update({
"userId": {
$in: [
"10000001",
"10000002"
]
}
},
[
{
"$set": {
"booksBought": {
"$cond": {
"if": {
"$in": [
"harry potter",
"$booksBought.booktitle"
]
},
"then": "$booksBought",
"else": {
"$concatArrays": [
"$booksBought",
[
{
"booktitle": "harry potter",
"quantity": 0
}
]
]
}
}
}
}
},
{
"$set": {
"booksBought": {
"$map": {
"input": "$booksBought",
"as": "bb",
"in": {
"$cond": {
"if": {
$eq: [
"harry potter",
"$$bb.booktitle"
]
},
"then": {
"$mergeObjects": [
"$$bb",
{
"quantity": {
"$add": [
"$$bb.quantity",
10
]
}
}
]
},
"else": "$$bb"
}
}
}
}
}
}
],
{
multi: true
})