The goal, is to lookup for object field value in user.inCart array, if the value is found, update the object field quntity. Else case push a new object to the array.
I have this code working fine:
Users.findOneAndUpdate({
id:req.user.id,
'inCart.item': req.body.item
},
{
$inc: {'inCart.$.quantity': req.body.quantity}
}).then(data=>{
if (data!=null) {
res.status(200)
} else{
Users.findOneAndUpdate({
id:req.user.id,
},{
$push : {inCart:{item:req.body.item, quantity: req.body.quantity} }
}).then(()=>res.status(200))
}
})
}
is there a way to do the same with a single reqest?
CodePudding user response:
Query
- you can do it with pipeline update MongoDB >= 4.2
- find the id
- filter to see if item exists (in code replace the
1with the item identifier (itemName/code etc)) - if
isNewItem=> add it to theinCardwith quantity 1 - else
$mapand update the quantity by 1
*instead of filter map, you could do it with 1 reduce also, but concatArrays is slower if you had like inCard>1000 items
update({"id":{"$eq":1}},
[{"$set":
{"isNewItem":
{"$eq":
[{"$filter":
{"input":"$inCard", "cond":{"$eq":["$$this.item", 1]}}},
[]]}}},
{"$set":
{"inCard":
{"$cond":
["$isNewItem",
{"$concatArrays":["$inCard", [{"item":1, "quantinty":1}]]},
{"$map":
{"input":"$inCard",
"in":
{"$cond":
[{"$eq":["$$this.item", 1]},
{"$mergeObjects":
["$$this", {"quantity":{"$add":["$$this.quantity", 1]}}]},
"$$this"]}}}]}}}, {"$unset":["isNewItem"]}])
CodePudding user response:
I hope this will solve your issue within mind the cart default quantity would be 0 or less than 1
Users.findOneAndUpdate({
id: req.user.id,
'inCart.item': req.body.item
}, {
$set: {
'inCart.$.quantity': {
$cond: {
if: {
$gte: ["inCart.$.quantity": 1]
},
then: {
$add: ["inCart.$.quantity", req.body.quantity]
},
else: req.body.quantity
}
}
}
})
