Search code examples
mongodbaggregate

MongoDB update document property array of strings $push if not present $pull if present


DATA = [
  {
    name: 'one',
    example: {
      arrayOfStrings: ['one', 'two', 'three']
    }
  }
]

db.getCollection('test').update(
  {name: 'one'},
  [
    {
      // From access.roles, if value is not there, then add it to array of strings.
      // if it is there, remove it from the array of strings.
    }
  ]
)

Something like below, but working.

{
  $cond: [
    {
      $in: ['one', '$example.arrayOfStrings']
    },
    {$pull: {'$example.arrayOfStrings': 'one'}},
    {$push: {'$example.arrayOfStrings': 'one'}},
  ]
}

Solution

  • When "one" does exist in the example.arrayOfStrings array, use the $filter operator to remove it from the array.

    Otherwise, use the $concatArrays operator by providing "one" in an array to perform adding the element to the array.

    db.collection.update({
      name: "one"
    },
    [
      {
        $set: {
          "example.arrayOfStrings": {
            $cond: [
              {
                $in: [
                  "one",
                  "$example.arrayOfStrings"
                ]
              },
              {
                $filter: {
                  input: "$example.arrayOfStrings",
                  cond: {
                    $ne: [
                      "$$this",
                      "one"
                    ]
                  }
                }
              },
              {
                $concatArrays: [
                  "$example.arrayOfStrings",
                  [
                    "one"
                  ]
                ]
              }
            ]
          }
        }
      }
    ])
    

    Demo @ Mongo Playground