I am working with node and trying to update data with a date stamp in a nested array of objects. My data structure is as follows:
{
_id:629f2f5e7aa147d6503957d0
kid_id:"629f2f5e7aa147d6503957ce"
inventory: [
{ size: "0",
purchased: "0",
used: [{}],
_id: "111111"
},
{ size: "1",
purchased: "10",
used: [
{ date: "06/08/22", count: "2"}
],
_id: "222222"
}
]
}
I want to target size 1 and add another object to the "used" array with { date: "06/09/22", count: "4"}
Long term goal, when there is another "count" entry with existing date, just increment the count. If it is a new date that is when I need a new object in the array.
I started with the code below but this is not right:
router.put('/used', auth, async (req, res) => {
let kidID = req.body.kid_id;
let size = req.body.size;
try {
const record = await InventoryRecord.updateOne(
{ kid_id: kidID },
{ $inc: { 'inventory.$[el].used': -1 } },
{ arrayFilters: [{ 'el.size': size }] }
);
console.log(record);
res.send(record);
} catch (error) {
res.send({ message: error.message });
}
});
Thanks in advance for any help
You can do something like this:
inventory
item we want to update and call it replace
replace
to two parts innerObj
(the obj with date to edit) and innerOthers
- rest of the arrayinnerObj
in case there were no matching document.innerObj
by 1.innerOthers
and innerObj
to newObj
.newObj
into inventory
. db.collection.aggregate([
{$addFields: {
replace: {
$first: {
$filter: {
input: "$inventory",
as: "item",
cond: {$eq: ["$$item.size", inputSize]}
}
}
}
}
},
{$addFields: {
innerObj: {
$filter: {
input: "$replace.used",
as: "item",
cond: {$eq: ["$$item.date", inputDate]}
}
},
innerOthers: {
$filter: {
input: "$replace.used",
as: "item",
cond: {$ne: ["$$item.date", inputDate]}
}
},
replace: "$$REMOVE"
}
},
{$set: {
innerObj: {
$cond: [
{$gt: [{$size: "$innerObj"}, 0]},
{$first: "$innerObj"},
{count: "0", date: inputDate}
]
}
}
},
{$set: {"innerObj.count": {$toString: {$add: [{$toInt: "$innerObj.count"}, 1]}}}},
{$set: {
newObj: {$concatArrays: ["$innerOthers", ["$innerObj"]]},
innerObj: "$$REMOVE",
innerOthers: "$$REMOVE"
}
},
{
$set: {
inventory: {
$map: {
input: "$inventory",
as: "item",
in: {
$mergeObjects: [
"$$item",
{$cond: [
{$eq: ["$$item.size", inputSize]},
{used: "$newObj"},
{used: "$$item.used"}
]}
]
}
}
},
newObj: "$$REMOVE"
}
}
])
See how it works on the playground example
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.