party
{
_id: new ObjectId('6570d8aef19ec1c690cc8d34'),
name: 'party',
items: [
{
name: 'Welcome to your todo list',
_id: new ObjectId('6570d8aaf19ec1c690cc8d31')
},
{
name: 'Hit the + button to add a new item.',
_id: new ObjectId('6570d8aaf19ec1c690cc8d32')
},
{
name: 'Hit this to delete an item.',
_id: new ObjectId('6570d8aaf19ec1c690cc8d33')
},
{ name: 'heya', _id: new ObjectId('6570ee634c6ed501ba04974a') },
{ name: 'hoiya', _id: new ObjectId('6570eea34c6ed501ba049778') },
{ name: 'heyty', _id: new ObjectId('6570ef6d934fb47039850682') },
{ name: 'dsfdsf', _id: new ObjectId('6570efcad07077740a80ce5a') },
{ name: 'hey', _id: new ObjectId('6570f193c6b50f3c3d692951') },
{ name: 'hiii', _id: new ObjectId('6570f1bcc6b50f3c3d69299b') }
],
}
I'm trying to access the _id
of the inner array (items
) to apply the delete on that ID. I want to delete the item by _id
but unfortunately I cannot wrap my head around the documentation/examples on the Mongoose docs website. I am currently using Mongoose
"mongoose": "^8.0.2"
so I would prefer a solution with the async/await method on NodeJS.
// Equivalent to `parent.children.pull(_id)`
parent.children.id(_id).deleteOne();
Apparently using both of those does not work for me it returns undefined
(I am probably not doing it right).
I am expecting to use the _id
of items to delete an item by ID.
Please suggest Mongoose methods only.
Mongoose has two mongoose-specific ways to handle this kind of operation. The first is the least efficient but easiest to understand.
This is a three step process that involves finding the document you want, pulling it from the array and then saving it back to the database. As you are making two calls to the db it is less efficient but logically clear to read:
// 1. Get the document that contains the object you want to delete
const document = await PartyModel.findOne({"items._id": _id});
// 2. Pull that object from the array
document.items.pull({_id: _id});
// 3. Save the changes
await document.save();
Model.findOneAndUpdate()
This is more efficient because it is a one step process that involves finding the document you want and passing in an update
document. That update document can be a mongodb operation such as the $pull
operator in @Yong Shun answer.
The major difference between findOneAndUpdate
and updateOne
is that findOneAndUpdate
will return the actual document back to you in either the state it was before you updated or the state after you updated which is configurable by you. Whereas, updateOne
will return an update status document contanining useful properties such as acknowledged
and modifiedCount
, but not any of the document data fields or values. If you need to return the document back to your front-end then use findOneAndUpdate
otherwise it makes no difference:
const document = await PartyModel.findOneAndUpdate({
'items._id': _id
},{
$pull: {
"items": {
_id: _id
}
}
}, { new:true }); //< This option says return me the document after the changes are made