Reputation: 71
I have mongo document and when a new order appear, I need to push it or update (increment the quantity) if an order of a part_id
already exist.
{
user_id: '13',
stock: [
{
part_id: 'P456',
quantity: 3
},
{
part_id: 'P905',
quantity: 8
}
]
}
I have a tried to use {upsert: true}
and $inc
but could not find the solution.
Upvotes: 1
Views: 4368
Reputation: 36104
I have a tried to use {upsert: true} and $inc but could not find the solution
The upsert will not support in array of object, you can try 2 queries first find and second update,
Count documents using countDocuments
:
let user_id = "13";
let part_id = "P456";
let hasDoc = await YourSchema.countDocuments({ user_id: user_id, "stock.part_id": part_id });
// Document already exists, so increment it value
if (hasDoc > 0) {
await YourSchema.updateOne(
{ user_id: user_id, "stock.part_id": part_id },
{ $inc: { "stock.$.quantity": 1 } }
);
}
// Document not exists then add document
else {
await YourSchema.updateOne(
{ user_id: user_id },
{ $push: { stock: { part_id: part_id, quantity: 1 } } }
);
}
Second Option: You can update with aggregation pipeline starting from MongoDB 4.2,
$cond
to check if part_id
is in stock
$map
to iterate loop of stock
and check condition if part_id
match then add 1 in quantity
otherwise return current objectpart_id
and quantity in stock
using $concatArrays
let user_id = "13";
let part_id = "P456";
db.collection.update(
{ user_id: user_id },
[{
$set: {
stock: {
$cond: [
{ $in: [part_id, "$stock.part_id"] },
{
$map: {
input: "$stock",
in: {
$cond: [
{ $eq: ["$$this.part_id", part_id] },
{
part_id: "$$this.part_id",
quantity: { $add: ["$$this.quantity", 1] }
},
"$$this"
]
}
}
},
{ $concatArrays: ["$stock", [{ part_id: part_id, quantity: 1 }]] }
]
}
}
}]
)
Upvotes: 6