Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoose deleting document references

I've got 2 schema's. One user schema, and a project schema. The user schema holds a reference to the project schema. User Schema:

const UserSchema = new Schema({
    username: {
        type: String,
        required: true
    },
    email: {
        type: String,
        required: true
    },
    password: {
        type: String,
        required: true
    },
    date: {
        type: Date,
        default: Date.now
    },
    projects: [
        {
            type: Schema.Types.ObjectId,
            ref: 'Project'
        }
    ]
});

Project schema:

const projectSchema = new Schema({
    experience: [
        {
            company: String,
            positionExperience: String,
            descriptionExperience: String,
            websiteExperience: String,
            timeperiodExperience: Array,
        }
    ],
    education: [
        {
            school: String,
            degree: String,
            descriptionEducation: String,
            websiteEducation: String,
            timeperiodEducation: Array
        },
    ],
}, {
        collection: 'project'
    });

When the currently logged in user saves a project, it gets pushed inside the projects array in the user schema with: user.projects.push(project);

I got a delete route which lets the user delete projects:

router.delete('/delete/:id', passport.authenticate('jwt', { session: false }), (req, res, next) => {
    Project.findByIdAndRemove({ _id: req.params.id }, (err) => {
        if (err) res.json(err)
        else res.json('Succesfully removed')
    });
})

However, the project id's are not removed from the currently logged in user's collection in the database. Log of DB:

"_id" : ObjectId("5d9474c2dccfb181dd8e9fde"),
    "projects" : [
        ObjectId("5d9474cddccfb181dd8e9fdf"),
        ObjectId("5d94753e9b610a81f83937e9"),
        ObjectId("5d947602f72f0f820f2974f0"),
        ObjectId("5d947ae435d2e982535d9a53"),
    ],
    "username" : "b",
    "password" : "$2a$10$4T1TjmFYD/01wEdMbiSRMeKNVKegnkVBOGGHasP.qJjVbQzmgEZDO",
    "email" : "b",

All of the projects are deleted but are their id's are still in the users record. I need some kind of garbage collection to remove those aswell. I looked at Cascade Delete. Cascade delete means that if a record in the parent table is deleted, then the corresponding records in the child table will automatically be deleted. In my case the user is the parent table and I'm not trying to delete a user, I'm trying to delete a project associated with the user. I've tried things like this:

User.findOne({ username: req.user.username }, (err, user) => {
    Project.remove({
        "_id": {
            $in: user.projects
        }
    }, function(err) {
        if(err) return next(err);
        user.deleteOne()
    })
})

But that deletes the whole user... How can I delete both a project from the projects collection and the projects corresponded with the logged in user? Thanks in advance.

* ----- EDIT ----- *

After some more digging, and thanks to the very usefull answers, this is what I came up with:

//delete route
router.delete('/delete/:id', passport.authenticate('jwt', { session: false }), (req, res, next) => {
    User.findOneAndUpdate({ username: req.user.username }, {
        $pull: {
            'projects': req.params.id
        }
    }, function (err, model) {
        if (!err) {
            Project.findByIdAndRemove({ _id: req.params.id }, (err) => {
                if (err) res.json(err)
                else res.json('Succesfully removed')
            });
        }
        else {
            res.status(500).json(err)
        }
    });
})
like image 624
Reinier68 Avatar asked Oct 26 '25 03:10

Reinier68


1 Answers

You would need to write your own remove function. Have a look at this question where this problem is already handled.

like image 178
Pastafari Avatar answered Oct 28 '25 17:10

Pastafari



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!