Anish Menon
Anish Menon

Reputation: 809

How to remove an element from inner array of nested array pymongo using $ pull

Here is my news document structure

{
"_id" : ObjectId("5bff0903bd9a221229c7c9b2"),
"title" : "Test Page",
"desc" : "efdfr",
"mediaset_list" : [ 
    {
        "_id" : ObjectId("5bfeff94bd9a221229c7c9ae"),
        "medias" : [ 
            {
                "_id" : ObjectId("5bfeff83bd9a221229c7c9ac"),
                "file_type" : "png",
                "file" : "https://aws.com/gg.jpg",
                "file_name" : "edf.jpg"
            }, 
            {
                "_id" : ObjectId("5bfeff83bd9a221229c7c9ad"),
                "file_type" : "mov",
                "file" : "https://aws.com/gg.mov",
                "file_name" : "abcd.mov"
            }
        ]
    }
]}

The queries that i've tried are given below

Approach 1

db.news.find_and_modify({},{'$pull': {"mediaset_list": {"medias": {"$elemMatch" : {"_id": ObjectId('5bfeff83bd9a221229c7c9ac')}} }}})

Approach 2

db.news.update({},{'$pull': {"mediaset_list.$.medias": {"_id": ObjectId('5bfeff83bd9a221229c7c9ac')}} })

Issue we are facing

The above queries are removing entire elements inside 'mediaset_list' . But i only want to remove the element inside 'medias' matching object ID.

Upvotes: 2

Views: 334

Answers (2)

Anish Menon
Anish Menon

Reputation: 809

From @micki's mongo shell query (Answer above) , This is the pymongo syntax which will update all news document with that media id .

db.news.update_many({}, 
    { 

    "$pull": 

        { "mediaset_list.$[item].medias": { "_id": ObjectId("5bfeff83bd9a221229c7c9ad") } } ,
     },
     array_filters=[{ "item._id": ObjectId("5bfeff94bd9a221229c7c9ae")}],

     upsert=True)

Upvotes: 1

mickl
mickl

Reputation: 49995

Since you have two nested arrays you have to use arrayFilters to indicate which element of outer array should be modified, try:

db.news.update({ _id: ObjectId("5bff0903bd9a221229c7c9b2") }, 
    { $pull: { "mediaset_list.$[item].medias": { _id: ObjectId("5bfeff83bd9a221229c7c9ad") } } },
    { arrayFilters: [ { "item._id": ObjectId("5bfeff94bd9a221229c7c9ae") } ] })

So item is used here as a placeholder which will be used by MongoDB to determine which element of mediaset_list needs to be modified and the condition for this placeholder is defined inside arrayFilters. Then you can use $pull and specify another condition for inner array to determine which element should be removed.

Upvotes: 2

Related Questions