Kim Kim - 1 month ago 7
Node.js Question

Find and delete document inside nested array

I am struggling to delete element inside nested arrray in mongoDB.

Lets say I have this schema:

var question = new Schema({
problem: {
type: String,
required: true
},
multipleChoices: [{
type: String,
required: true
}],
correctAnswer: {
type: Number,
required: true
}
});

var testCategorySchema = new Schema({
category: {
type: String,
required: true
},
tests: [{
version: {
type: String,
required: true
},
questions: [question]
}]
});


For example I have instance of that schema like this:

{
category: "Math",
tests: [
{
_id : ObjectId("580859310a0d4b40ac1c6034"),
version: "1A",
questions: [
{
problem: "blablabla",
multiplechoices: [
"bla bla", "blb blb", "blc blc"
],
correctAnswer: 1
},
{
problem: "blibliblibli",
multiplechoices: [
"bla bla", "blb blb", "blc blc"
]
correctAnswer: 1
}
]
},
{
_id : ObjectId("580859310a0d4r40ax1c5034"),
version: "1B",
questions: [
{
problem: "auauauauau",
multiplechoices: [
"bla bla", "blb blb", "blc blc"
]
correctAnswer: 1
},
{
problem: "blibliblibli",
multiplechoices: [
"bla bla", "blb blb", "blc blc"
]
correctAnswer: 1
}
]
}
]
}


For example, how can I delete problem: "blablabla" in category math and version 1A using mongooseJS?

I already to delete problem in math category and version 1A using this code:

TestCategory
.findOne(
{
category: req.params.testCategory,
'tests.version': req.params.testVersion
},
{
'tests.version.$': 1
}
)
.then(function(testVersion) {
res.send(testVersion);
})
.catch(function(err) {
console.log(err);
next(err);
});


For example I search math category and version 1A, the result from that code is like this:

_id: "580859190a0d4b40ac1c6033",
tests: [
{
_id : ObjectId("580859310a0d4b40ac1c6034"),
version: "1A",
questions: [
{
problem: "blablabla",
multiplechoices: [
"bla bla", "blb blb", "blc blc"
],
correctAnswer: 1
},
{
problem: "blibliblibli",
multiplechoices: [
"bla bla", "blb blb", "blc blc"
]
correctAnswer: 1
}
]
}
]


The result already filtered, so only version 1A is displayed (although categoryId is still displayed). Now I am confused how to delete the question in proper and good way.

Answer

You need to use update with the positional operator $ in order to update the correct test and then use $pull to remove the question:

TestCategory.update(
    {
        category: 'Math',
        'tests.version': '1A'
    },
    {
        $pull: {
            'tests.$.questions': { problem: 'blablabla' }
        }
    }
)