Home > Back-end >  delete where all keys of a map are contained in a list in mongodb
delete where all keys of a map are contained in a list in mongodb

Time:10-14

I have this:

  • A field which is a map where the keys are UUIDs and the value another object which is not relevant.
  • A list of UUIDs that should be passed as parameter.

I want to:

delete from the collection all documents where all keys of the map are included in the list of UUIDs

The object:

@Document
public class MyClass
{
  private Map<UUID, anotherObject> myMap;
}

With derived queries I am not able to reach the UUID because has no name -> deleteByMyMap...

And with a query I know that there is a way to convert the map into an array ($expr and $objectToArray) but I do not know if it makes sense.

  • Is there any way to do this?
  • How can I access just the key of the map?

CodePudding user response:

try this it might help: Get keys in a single document You can also use aggregation to get keys in a single document:

db.activities.aggregate([ {"$project":{"arrayofkeyvalue":{"$objectToArray":"$$ROOT"}}}, {"$project":{"keys":"$arrayofkeyvalue.k"}} ])

to delete:

db['name1.name2.name3.Properties'].remove([ { "key" : "name_key1" }, { "key" : "name_key2" }, { "key" : "name_key3" } )]

CodePudding user response:

This is one way of doing it, use an aggregation pipeline to get _id of all documents matching your criteria:

db.collection.aggregate([
  {
    "$addFields": {
      keysOfMap: {
        "$map": {
          "input": {
            "$objectToArray": "$myMap"
          },
          "as": "item",
          "in": "$$item.k"
        }
      },
      
    }
  },
  {
    "$addFields": {
      "difference": {
        "$setDifference": [
          "$keysOfMap",
          [
            "63f62530-89b1-439e-bcb3-2c7ab614ecda",
            "dcbb1469-3ca0-4547-b7d1-296ba2f0a01d"
          ]
        ]
      }
    }
  },
  {
    "$match": {
      difference: []
    }
  },
  {
    "$project": {
      _id: 1
    }
  }
])

How it works:

  1. At first, the map the converted into an array, and then that array is mapped to the keys.
  2. Then the difference, between the keys array and the list of ids is calculated.
  3. Then all documents having empty differences are picked up and their _id is projected.

Using these ids, you can simply do:

db.collection.remove({_id: {$in: [// the list here]}});

Playground for the aggregation.

  • Related