Reputation: 31
Hi all thanks for looking to my question, I would like to delete a child referenced in a parent here is the structure:
const parentSchema: = new Schema({
name: String,
child: { type: mongoose.Schema.Types.ObjectId, ref:'Child' },
})
const childSchema: = new Schema({
name: String,
})
the child is saved to its own child collection and the parent contains its reference.
my approach for this is as follow:
parentSchema.statics.deleteByID = async function (id: string) {
try {
const parent = await this.findOne({ id })
const child = await Child.findOne({_id: parent.child })
const childDel = child && await child.remove()
const parentDel = await parent.remove()
console.log(parent, child, childDel, parentDel)
} catch(err) {
throw new Error(err)
}
}
this works just fine, i wanted to know if this is the best approach.
Upvotes: 3
Views: 3053
Reputation: 31
I think this is the best approach for my problem, hope it helps anyone. My problem was in thinking that the pre('remove') hook would be triggering on Class call, but it is called only on instance. So rather than Parent.deleteOne(), i first find the instance i want to delete with findOne(), and then trigger the pre('remove') with parent.remove(), and delete necessary childs... Here is an example:
parentSchema.pre<ParentDocument>('remove', async function() {
try {
if (this.child01) {
await Child01.deleteOne({ _id: this.child01 })
}
if (this.child02) {
await Child02.deleteOne({ _id: this.child02 })
}
} catch(err) {
throw new Error(err)
}
})
parentSchema.statics.deleteByID = async function (id: string) {
try {
const parent = await this.findOne({ id })
return !!(parent && await parent.remove())
} catch(err) {
throw new Error(err)
}
}
Upvotes: 0
Reputation: 17858
I don't think if mongoose has this feature built-in.
The best you can do is to create a remove middleware as described here:
By the way, to make your existing code shorter, you can use findByIdAndDelete
. It returns the deleted document, so with the following code 2 database hits make the job:
const parentDel = await Parent.findByIdAndDelete(id);
const childDel = await Child.deleteOne({_id: parentDel.child});
console.log(parentDel, childDel);
parentDel will look like this:
{
"_id": "5de0114ad068f335b480925a",
"name": "Parent 1",
"child": "5de01144d068f335b4809259",
"__v": 0
}
And childDel will look like this:
{
"n": 1,
"ok": 1,
"deletedCount": 1
}
Upvotes: 1