I'm trying to update a nested array in a document only if the array does not already include the item like so:
await userCollection.findOneAndUpdate(
{ _id: ObjectId('616acc597ebda90ca6ffee21') },
{
'devices': {
$push: {
$cond: {
if: {
$in: [req.body.serial, '$devices']
},
then: '$devices',
else: { serial: req.body.serial, data: [] }
}
}
}
},
{ returnOriginal: false },
(err, _) => {
if (err) {
return res.status(400);
} else {
return res.status(200).json(user.value);
}
}
);
This is my user object:
{
"_id": "616acc597ebda90ca6ffee21",
"username": "[email protected]",
"displayName": "Test",
"devices": [
{
"serial": "865674036421275",
"data": [
{
"timestamp": "2021-10-16T12:36:35.799Z"
},
{
"timestamp": "2021-10-16T12:41:33.633Z"
},
{
"timestamp": "2021-10-16T12:52:03.055Z"
}
]
},
],
"hashedPassword": "R5vt3vY7vEvTHvhC7YGNOWuIjBUQGLqsd92QGE06tjU=",
"salt": "6RS0OVIFboCkIEPHdZmTcQ==",
"dateCreated": "2021-10-16T12:58:00.294Z"
}
How will I check if serial is already in devices? Also, is it possible to throw an error if it already exists?
Query
eq/ne query operators, we can do arrays=value, if array has the value its true)"000" with the serial you want to add*it will be fast, and you dont need an index on devices.serial
because it selects a specific document already with the _id match
Test code here
db.collection.update({
"_id": ObjectId("616acc597ebda90ca6ffee21"),
"devices.serial": {
"$ne": "000"
}
},
{
"$push": {
"devices": {
"serial": "000",
"data": []
}
}
})
We cant mix update operators with aggregate operators.
$cond is aggregate operator, it cant be mixed with $push update operator. (aggregate $push is for group, cant add to an array)
We can do the update with update pipeline, but here a normal update is simpler.
There's an update operator called addToSet
check it here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With