Search code examples
arraysmongodbmongoosesubdocument

Removing an element from an array of subdocuments by subdocumentId


So I have the following schema:

var questionsSchema = new Schema({
        nr: Number,
        points: Number,
        description: String,
        groups: [{
            type: Schema.Types.ObjectId,
            ref: 'Group',
            default: []
        }],
        createdOn: {type: Date, default: Date.now()},
        isActive: {type: Boolean, default: true}
    });

var roundSchema = new Schema({
        name: String,
        index: Number,
        questions: [ questionsSchema ]
    });

Now I have an operation to remove a question (questions are unique) without having the round (parent) _id.

I've looked here on how to pull an element from an array, however I simply can't find the correct way to do this, in the link it's an array of non-documents so that's a bit different from my situation.

What I've tried:

function removeQuestionById(req, res) {
        Round.update({"questions._id": req.params.id}, {$pull: {"questions._id": req.params.id}}, function(err, rowsAffected){
            if(err){
                res.sendStatus(500);
                return console.log("An error occured when trying to remove a question!", err);
            }
            console.log("Amount of rows affected was " + rowsAffected);
            return res.end();
        })
    }

Didn't work, so I assumed I just had to specify the field of the subdocument in the update statement:

function removeQuestionById(req, res) {
        Round.update({"questions._id": req.params.id}, {$pull: {"_id": req.params.id}}, function(err, rowsAffected){
            if(err){
                res.sendStatus(500);
                return console.log("An error occured when trying to remove a question!", err);
            }
            console.log("Amount of rows affected was " + rowsAffected);
            return res.end();
        })
    }

Also didn't work, my amount of rows affected in both situations is 0. I've tried several other things over the last few hours, none of them worked.

Note: The question _id is correct in the request object.


Solution

  • I have finally got this to work, however I did require the parent _id to do this:

    Round.update({"_id": req.params.roundId}, {$pull: {"questions": {"_id": req.params.questionId}}},function cb(err) {
                if(err){
                    res.sendStatus(500);
                    return console.log("An error occured when trying to remove a question!", err);
                }
                return res.end();
            });
    

    If anyone knows a way to do this without requiring the parentId, please do tell.

    EDIT: Found it, just replace _id by questions._id andoffcourse the correct param value