Home > Back-end >  Mongoose remove subdocument
Mongoose remove subdocument

Time:09-18

I am struggling to get subdocument removed from the parent. I am using Mongoose findOneAndUpdate.

unitRouter.delete('/:id/contracts/:cid', async (req, res) => {
    Unit.findOneAndUpdate(
        { id: req.params.id }, 
        {$pull: {contracts: { id: req.params.cid }}}, 
        function(err, data){
            console.log(err, data);
      });
    res.redirect(`/units/${req.params.id}`);
});

Schema is as follows:

const unitSchema = new mongoose.Schema({
    address: {
        type: String,
        required: true
    }
    contracts: [{type: mongoose.Schema.Types.ObjectId, ref: 'Contract'}]
});

And it doesn't remove it from the list, neither from the contract collection. I have checked similar topics, but didn't got it to work. What am I missing?

CodePudding user response:

First of all, your schema does not match with your query.

  1. Your schema doesn't have any id. Do you mean _id created by default?
  2. contracts field is an array of ObjectId, not an object like { id: XXX }

So, starting from the schema you can have a collection similar to this:

[
    {
        "contracts": [
            "5a934e000102030405000000",
            "5a934e000102030405000001",
            "5a934e000102030405000002" 
        ],
        "_id": "613bd938774f3b0fa8f9c1ce",
        "address": "1"
    },
    {
        "contracts": [
            "5a934e000102030405000000",
            "5a934e000102030405000001",
            "5a934e000102030405000002"
        ],
        "_id": "613bd938774f3b0fa8f9c1cf",
        "address": "2"
    }
]

With this collection (which match with your schema) you need the following query:

Unit.updateOne({
  "_id": req.params.id
},
{
  "$pull": {
    "contracts": req.params.cid
  }
})

Example here.

Also, the inverse way, your query is ok but your schema doesn't. Then you need a schema similar to this:

new mongoose.Schema(
  {
    id:{
      type: mongoose.Schema.Types.ObjectId,
      required: true
    },
    address: {
      type: String,
      required: true
  },
  contracts: [{
    id:{
      type: mongoose.Schema.Types.ObjectId,
      ref: 'Contract'
    }
  }]
  });

Example here

By the way, take care to not confuse between id and _id. By default is created the field _id.

  • Related