APE
APE

Reputation: 1170

Mongoose - Remove several objects from an array (not exact match)

I have a collection Playlist that contains an array of items

{

    userId: {
        type        : String,
        required    : true,
        index       : true,
        unique      : true
    },

    items: [
        {
            id: { // do not mix up with _id, which is the autogenerated id of the pair {id,type}. ID is itemId
                type        : Schema.Types.ObjectId
            },
            type: {
                type        : String
            }
        }
    ]

}

Mongo automatically adds the _id field to the items when I push a pair {id,type} to items (but I don't care about it).

Now I would like to remove several "pairs" at once from the items array.

I have tried using $pullAll but it requires an exact match, and I do not know the _id, so it does not remove anything from items

playlistModel.update({userId:userId},{$pullAll:{items:[{id:"123",type:"video"},{id:"456",type:"video"}]}},null,function(err){

I have tried using $pull with different variants, but it removed ALL objects from items

playlistModel.update({userId:userId},{$pull:{items:{"items.id":{$in:["123","456"]}}}},null,function(err){

playlistModel.update({userId:userId},{$pull:{items:{$in:[{id:"123",type:"video"},{id:"456",type:"video"}]}}},null,function(err){

Am I missing something or am I asking something that isn't implemented?

If the latter, is there a way I can go around that _id issue?

Upvotes: 0

Views: 1824

Answers (2)

APE
APE

Reputation: 1170

OK I found a way that works using $pull:

playlistModel.update({userId:userId},{$pull:{items:{id:{$in:["123","456"]}}}},null,function(err){ 

It doesn't take the type into account but I can't see any issue with that since the id is unique across all types anyway.

Although I will wait a bit to see if someone has a better solution to offer

EDIT

With Veeram's help I got to this other solution, which IMO is more elegant because I don't have _ids that I don't need in the database, and the $pullAll option seems more correct here

var playlistItemSchema = mongoose.Schema({
    id: { // do not mix up with autogenerated _id. id is itemId
        type        : Schema.Types.ObjectId
    },
    type: {
        type        : String
    }
},{ _id : false });

var schema = new Schema({

    userId: {
        type        : String,
        required    : true,
        index       : true,
        unique      : true
    },

    items: [playlistItemSchema]

});


playlistModel.update({userId:userId},{$pullAll:{items:[{id:"123",type:"video"},{id:"456",type:"video"}]}},null,function(err){

Upvotes: 1

vingo
vingo

Reputation: 26

tips: you can use _id field to handle your playlistModel data.

mongoose api : new mongoose.Types.ObjectId to generate an Object_id

let _id=new mongoose.Types.ObjectId;
     playlistModel.updateMany({_id:_id},{ $set: { name: 'bob' }}).exec(data=>{console.log('exec OK')});

Upvotes: 0

Related Questions