Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

$addToSet in update aggregation

I have a MongoDB update aggregation pipeline which I need to extend with $addToSet as I want to new elements to an array but I cannot mange to make it work with the aggregation pipeline.

MongoDB Playground: https://mongoplayground.net/p/9f_rS2QjLR_

Document to update:

  {
    "_id": 1,
    "arr": [
      "foo",
      "bar"
    ]
  }

Aggregation pipeline:

db.collection.update({
  "_id": 1,
  
},
[
  {
    "$set": {
      "arr": {
        $addToSet: {
          "$arr": {
            $each: [
              "bar",
              "baz"
            ]
          }
        }
      }
    }
  }
])

Expected output:

  {
    "_id": 1,
    "arr": [
      "foo",
      "bar",
      "baz"
    ]
  }

If it isn't possible to use the $addToSet operator how can I manually create the same behaviour using other operators?

like image 701
quieri Avatar asked Dec 19 '25 21:12

quieri


1 Answers

1. $addToSet with Normal Update Query (duplicate values will be removed)
demo

db.collection.update({
  _id: 1
},
{
  $addToSet: {
    arr: "baz"
  }
})

If you want to add multiple elements into array use $each like
demo

db.collection.update({
  _id: 1
},
{
  $addToSet: {
    arr: {
      $each: [
        "baz",
        "abc",
        "def"
      ]
    }
  }
})

2. can use $concatArrays with aggregation (duplicate values not removed)
demo

db.collection.aggregate([
  {
    $match: {
      _id: 1
    }
  },
  {
    $project: {
      arr: {
        $concatArrays: [
          "$arr",
          [
            "baz",
            "abc",
            "bar"  //will be duped
          ]
        ]
      }
    }
  }
])

Starting in MongoDB 4.2, you can use the aggregation pipeline for update operations. With the update operations, the aggregation pipeline can consist of the following stages: $addFields $set $project $unset $replaceRoot $replaceWith

therefore can use $project demo

db.collection.update({
  _id: 1
},
[
  {
    $project: {
      arr: {
        $concatArrays: [
          "$arr",
          [
            "baz",
            "abc",
            "bar"  //will be duped
          ]
        ]
      }
    }
  }
])

3. can use $setUnion with aggregation (duplicate values will be removed)
demo

db.collection.aggregate([
  {
    $match: {
      _id: 1
    }
  },
  {
    $project: {
      arr: {
        $setUnion: [
          "$arr",
          [
            "baz",
            "abc",
            "bar"  //will not be duped
          ]
        ]
      }
    }
  }
])

or
demo

db.collection.update({
  _id: 1
},
[
  {
    $project: {
      arr: {
        $setUnion: [
          "$arr",
          [
            "baz",
            "abc",
            "bar"   //will not be duped
          ]
        ]
      }
    }
  }
])
like image 192
cmgchess Avatar answered Dec 22 '25 10:12

cmgchess



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!