2

I am trying to remove an entry in an array that is a sub property of a document field. The data for a document looks like this:

{
    _id: 'user1',
    feature: {
        enabled: true,
        history: [
            {
                _id: 'abc123'
                ...
            }
        ]
    },
    ...
}

For some reason I have not been able to remove the element using $pull and I'm not sure what is wrong.

I've looked at the official docs for $pull, this well-known answer, as well this one and another.

I have tried the following query

db.getCollection('userData').update({ _id:'user1' }, {
    $pull: {
        'feature.history': { _id: 'abc123' }
    }
})

and it has no effect. I've double-checked _id and it is a proper match. I've also tried filtering based on the same entry, thinking I need to target the data I'm trying to remove:

db.getCollection('userData')
    .update({ _id: 'user1', 'feature.history': { _id: 'abc123' }, { ... })

So far no luck

Felipe
  • 10,606
  • 5
  • 40
  • 57
  • what is the type of the `_id`? because if it is objectId then you need to cast your id – Ashh Jul 16 '18 at 16:30
  • it's a mongodb `ObjectId`. How should it be cast? – Felipe Jul 16 '18 at 16:42
  • `$pull: { 'feature.history': { _id: mongoose.Types.ObjectId('your_id_field') } }` Try this – Ashh Jul 16 '18 at 16:43
  • that was it. I thought mongodb implicitly converted `_id` fields when querying, but using `ObjectId()` in my original query modified the record successfully. Thanks! Can you add this as an answer and I will accept it – Felipe Jul 16 '18 at 16:47

2 Answers2

1

You need to cast your id to mongoose ObjectId

db.getCollection('userData').update(
   { "_id": "user1" },
   { "$pull": { "feature.history": { "_id": mongoose.Types.ObjectId(your_id) } }
})
Ashh
  • 44,693
  • 14
  • 105
  • 132
  • The source of the issue is that I was passing the `_id` through a socket.io message, causing it to turn into a string in the back end. I am not using mongoose, but using the mongo type worked successfully: `const ObjectId = require('mongodb').ObjectId` and later `_id: ObjectId('..')` – Felipe Jul 16 '18 at 17:05
  • Ok I got it what was the issue here... There is not need to cast if you would have used mongoose... But in mongodb queries you have to cast it – Ashh Jul 16 '18 at 17:08
0
db.getCollection('userData').update({ _id:'user1', "feature.history._id" : "abc123" }, {
    $pull: {
        'feature.history.$._id': 'abc123'
    }
})
Prajval M
  • 2,298
  • 11
  • 32