In MongoDB, the $addToSet
operator adds a value to an array unless the value is already present in the array.
It’s similar to the $push
operator, except that $push
adds the value even if the value is already present.
Example
Suppose we have a collection called products
with the following documents:
db.products.find()
Result:
{ "_id" : 1, "product" : "Bat", "sizes" : [ "S", "M", "L" ] } { "_id" : 2, "product" : "Hat", "sizes" : [ "S", "L", "XL" ] } { "_id" : 3, "product" : "Cap", "sizes" : [ "S", "M", "L", "XL" ] }
We can use $addToSet
to append a value to one of those arrays.
Example:
db.products.update(
{ _id: 1 },
{ $addToSet: { sizes: "XL" } }
)
Output:
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
Let’s take another look at our collection to verify the change:
db.products.find()
Result:
{ "_id" : 1, "product" : "Bat", "sizes" : [ "S", "M", "L", "XL" ] } { "_id" : 2, "product" : "Hat", "sizes" : [ "S", "L", "XL" ] } { "_id" : 3, "product" : "Cap", "sizes" : [ "S", "M", "L", "XL" ] }
Duplicate Values
If you try to insert a value that already exists in the array, nothing happens. In other words, $addToSet
only inserts the value if it doesn’t already exist.
Here’s an example of attempting to insert a value that already exists.
db.products.update(
{ _id: 1 },
{ $addToSet: { sizes: "XL" } }
)
Output:
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })
This message tells us that there was one matching document (i.e. the document with an _id
of 1
), but there were no modifications.
In the previous example we saw "nModified" : 1
, but in this example we see "nModified" : 0
. That’s because the value didn’t exist when we inserted it in the previous example, but in this example it already exists.
We can verify this by looking at the collection again:
db.products.find()
Result:
{ "_id" : 1, "product" : "Bat", "sizes" : [ "S", "M", "L", "XL" ] } { "_id" : 2, "product" : "Hat", "sizes" : [ "S", "L", "XL" ] } { "_id" : 3, "product" : "Cap", "sizes" : [ "S", "M", "L", "XL" ] }
Add Multiple Values
You can use the $each
modifier to append multiple values to an array.
Example:
db.products.update(
{ _id: 2 },
{
$addToSet: {
sizes: {
$each: [ "XXL", "XXXL" ]
}
}
}
)
Output:
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
Now let’s check the collection again:
db.products.find()
Result:
{ "_id" : 1, "product" : "Bat", "sizes" : [ "S", "M", "L", "XL" ] } { "_id" : 2, "product" : "Hat", "sizes" : [ "S", "L", "XL", "XXL", "XXXL" ] } { "_id" : 3, "product" : "Cap", "sizes" : [ "S", "M", "L", "XL" ] }
We can see that the two values were appended to the array in document 2 as expected.
Add an Array to the Array
You can also append a whole array to the array. When you do this, the whole array is appended as its own separate array.
Suppose we have a collection like this:
db.foo.find()
Result:
{ "_id" : 1, "bar" : [ 1, 5, 3 ] } { "_id" : 2, "bar" : [ 8, 17, 18 ] } { "_id" : 3, "bar" : [ 15, 11, 8 ] }
We can append an array to an array like this:
db.foo.update(
{ _id: 1 },
{ $addToSet: { bar: [ 7, 8, 9] } }
)
Output:
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
Check the collection:
db.foo.find()
Result:
{ "_id" : 1, "bar" : [ 1, 5, 3, [ 7, 8, 9 ] ] } { "_id" : 2, "bar" : [ 8, 17, 18 ] } { "_id" : 3, "bar" : [ 15, 11, 8 ] }