1

my database has a structure like this:

  {
    "universe": "comics",
    "saga": [
      {
        "name": "x-men",
        "characters": [
          {
            "character": "wolverine",
            "powers": [
              {
                "power": "self-recovery"
              },
              {
                "power": "Super strength"
              },
              {
                "power": "steels claws"
              }
            ]
          },
          {
            "character": "cyclops",
            "powers": [
              {
                "power": "rays"
              },
              {
                "power": "Super strength"
              }
            ]
          }
        ]
      }
    ]
  },
  {
    "universe": "comics",
    "saga": [
      {
        "name": "spiderman",
        "characters": [
          {
            "character": "venom",
            "powers": [
              {
                "power": "Super strength"
              }
            ]
          }
        ]
      }
    ]
  }

I basically want to learn how to do operations with complex arrays, this time I think I will learn too much if I get the answer to this question. I want to delete the objects where "power:"self-recovery"

something like $.saga.characters.$.powers

I don't know how to do it because of the number of levels this property is under the main root.

normally i would use something like that:

db.mydb.update(
    {
    saga: {
        $elemMatch: { saga.characters.$ },
    },
    },

    { $pull: { powers: { power: "Super strength"
    } }},
    {
    new: true,
    multi:true
    },

for this example it should delete as many objects where {" power ":" self-recovery"} (in this case, only one object is deleted, which is where the character is wolverine)

but i don't know how to do what i need.

yavg
  • 2,761
  • 7
  • 45
  • 115
  • try `updateMany` and look at this question https://stackoverflow.com/a/50197290/8987128 just need to put your object keys as per operation, – turivishal Jul 17 '20 at 17:33

2 Answers2

1

Try the positional all $[] operator in MongoDb 3.6+

var query = {
    universe: 'comics'
};

var update = {
    $pull: {
        'saga.$[].characters.$[].powers': {
            power: 'self-recovery'
        }
    }
};
var options = {
    multi: true
};
db.collection.update(query, update, options);
Kunal Mukherjee
  • 5,775
  • 3
  • 25
  • 53
  • what means "$[]"? is neccesary put "[]" – yavg Jul 17 '20 at 18:37
  • $[] applies the pull operation for all the sub-documents inside the array which matches the criteria – Kunal Mukherjee Jul 17 '20 at 18:38
  • thanks! if i just use the `$` operator without `[]` won't it work? – yavg Jul 17 '20 at 18:40
  • can you help me with this please? this question has a bounty https://stackoverflow.com/questions/62988071/how-can-i-return-the-element-im-looking-for-inside-a-nested-array/63029063#63029063 – yavg Jul 22 '20 at 17:24
0
db.test.update(
  {
    "saga.characters.powers": {
      "$elemMatch": {
        "power": "self-recovery"
      }
    }
  },
  {
    "$pull": {
      "saga.$[].characters.$.powers": { 
       "power":"self-recovery"
      }
    }
  }
)

It removes the respective power object.It results

/* 1 */
{
    "_id" : ObjectId("5f11e25a9e001b53e39985fd"),
    "universe" : "comics",
    "saga" : [ 
        {
            "name" : "x-men",
            "characters" : [ 
                {
                    "character" : "wolverine",
                    "powers" : [ 
                        {
                            "power" : "Super strength"
                        }, 
                        {
                            "power" : "steels claws"
                        }
                    ]
                }, 
                {
                    "character" : "cyclops",
                    "powers" : [ 
                        {
                            "power" : "rays"
                        }, 
                        {
                            "power" : "Super strength"
                        }
                    ]
                }
            ]
        }
    ]
}

Kindly check and let me know missing things

Gibbs
  • 21,904
  • 13
  • 74
  • 138