skip to Main Content

In my example project, I have employees under manager. Db schema is like this;

{
  "employees": [
    {
      "name": "Adam",
      "_id": "5ea36b27d7ae560845afb88e",
      "bananas": "allowed"
    },
    {
      "name": "Smith",
      "_id": "5ea36b27d7ae560845afb88f",
      "bananas": "not-allowed"
    },
    {
      "name": "John",
      "_id": "5ea36b27d7ae560845afb88g",
      "bananas": "not-allowed"
    },
    {
      "name": "Patrick",
      "_id": "5ea36b27d7ae560845afb88h",
      "bananas": "allowed"
    }
  ]
}

In this case Adam is allowed to eat bananas and Smith is not. If I have to give the permission of eating bananas from Adam to Smith I need to perform update operation twice like this:

db.managers.update(
    { 'employees.name': 'Adam' },
    { $set: { 'employees.$.bananas': 'not-allowed' } }
);

and

db.managers.update(
    { 'employees.name': 'Smith' },
    { $set: { 'employees.$.bananas': 'allowed' } }
);

Is it possible to handle this in a single query?

2

Answers


  1. db.managers.update(
       {
          $or: [
             {"employees.name": "Adam"},
             {"employees.name": "Smith"}
          ]
       },
       {
          $set: {
             "employees.$[e].bananas": {
                $cond: [{ $eq: ["$e.name", "Adam"] }, "not-allowed", "allowed"]
             }
          }
       },
       {
          arrayFilters: [{ "e.name": { $in: ["Adam", "Smith"] } }]
       }
    )
    
    Login or Signup to reply.
  2. You can use $map and $cond to perform conditional update to the array entries depending on the name of the employee. A $switch is used for potential extension of cases.

    db.collection.update({},
    [
      {
        "$set": {
          "employees": {
            "$map": {
              "input": "$employees",
              "as": "e",
              "in": {
                "$switch": {
                  "branches": [
                    {
                      "case": {
                        $eq: [
                          "$$e.name",
                          "Adam"
                        ]
                      },
                      "then": {
                        "$mergeObjects": [
                          "$$e",
                          {
                            "bananas": "not-allowed"
                          }
                        ]
                      }
                    },
                    {
                      "case": {
                        $eq: [
                          "$$e.name",
                          "Smith"
                        ]
                      },
                      "then": {
                        "$mergeObjects": [
                          "$$e",
                          {
                            "bananas": "allowed"
                          }
                        ]
                      }
                    }
                  ],
                  default: "$$e"
                }
              }
            }
          }
        }
      }
    ])
    

    Mongo Playground

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search