Filippo oretti
Filippo oretti

Reputation: 49883

Mongoose - delete subdocument array item

I have this little schema for users:

{
 username: String,
 contacts: Array
}

So for example some user's contacts will look like this:

{
 username: "user",
 contacts: [{'id': ObjectId('525.....etc'), 'approved': false}, {'id':ObjectId('534.....etc'), 'approved': true}]
}

Now I need to delete an item from contacts so I do:

model.findByIdAndUpdate(23, {'$pull': {
              'contacts':{'id':'525.....etc'}
              }});

but seems not working, no errors but it doesn't gets deleted, I just would like to return this document for the user:

{
     username: "user",
     contacts: [{'id':ObjectId('534.....etc'), 'approved': false}]
    }

how to achieve this?

Upvotes: 11

Views: 12974

Answers (3)

clds84
clds84

Reputation: 11

Is 23 in the query referencing the placement in the array or is that the is for the model?

model.findByIdAndUpdate(23, {
  '$pull': {
    'contacts':{ '_id': new ObjectId(someStringValue) }
  }
});

Upvotes: 0

Stan Smith
Stan Smith

Reputation: 111

finaly!

MongoDB:

"imgs" : {"other" : [ {
        "crop" : "../uploads/584251f58148e3150fa5c1a7/photo_2016-11-09_21-38-55.jpg",
        "origin" : "../uploads/584251f58148e3150fa5c1a7/o-photo_2016-11-09_21-38-55.jpg",
        "_id" : ObjectId("58433bdcf75adf27cb1e8608")
                                    }
                            ]
                    },
router.get('/obj/:id',  function(req, res) {
var id = req.params.id;



Model.findOne({'imgs.other._id': id}, function (err, result) {
        result.imgs.other.id(id).remove();
        result.save();            
    });

Upvotes: 4

Neil Lunn
Neil Lunn

Reputation: 151220

The $pull operator actually just performs the conditions on the array element on which it is operating. It seems that your question might not actually show that you are probably working with an ObjectId value that mongoose creates by default for all array fields.

So you could to your query like this, after importing the ObjectId creation method:

model.findByIdAndUpdate(23, {
    '$pull': {
        'contacts':{ '_id': new ObjectId(someStringValue) }
    }
});

Or in fact you can actually define your "schema" a little better, and mongoose will actually "autocast" the ObjectId for you based on the "type" defined in the schema:

var contactSchema = new Schema({
    approved: Boolean
});

var userSchema = new Schema({
    username: String,
    contacts: [contactSchema]
});

This allows mongoose to "follow the rules" for strictly typed field definitions. So now it knows that you actually have an _id field for each element of the contacts array, and the "type" of that field is actually an ObjectId so it will automatically re-cast "String" values supplied as a true ObjectId.

Upvotes: 17

Related Questions