MongoDb: Difference between $push/$addtoset
$addToSet
do not add the item to the given field if it already contains it, on the other hand $push
will add the given object to field whether it exists or not.
{_id: "docId", items: [1, 2]}
db.items.update({_id:"docId"}, {$addToSet:{items: 2}}); // This won't update the document as it already contains 2
db.items.update({_id:"docId"}, {$push: {items:2}}); // this will update the document. new document {_id: "docId", items:[1,2,2]}
$push - adds items in the order in which they were received. Also you can add same items several times.
$addToSet - adds just unique items, but order of items is not guaranteed.
If you need to add unique items in order, you can group and add elements via $addToSet, then $unwind the array with elements, $sort by items, and then do $group again with $push items.
Along side the differences that others have mentioned
-
$push
: Appends an object to an array -
$addToSet
: Adds an object to an array if it does not exists
There is a difference in replication. (This can be seen if by taking a look at local.oplog.rs
)
-
$push
operations (that actually modified the array) are replicated as$set.items.INDEX: item
-
$addToSet
operations (that actually modified the array) are replicated as$set.items: [THE_ENTIRE_ARRAY]
If you are dealing with large arrays, then the difference might be significant
So while something like (the typical use case to maintain unique array)
db.items.updateOne(
{_id: 'my-id', 'items': {'$ne': 'items1'},
{'$push': {
'items': 'item1',
}}
)
db.items.updateOne(
{_id: 'my-id'},
{'$addToSet': {
'items': 'item1',
}}
)
might end up with the same resulting document, there is a difference in the replicated operation.
As the name suggest $addToSet (set) wont allow duplicates while $push simply add the element to array