MongoDB Array Update Operators: $push, $pull, $addToSet, $pop & Positional $
Learn every MongoDB array update operator — $push, $pull, $pullAll, $addToSet, $pop, the positional $, $[], $[identifier], and modifiers like $each, $position, $slice, $sort.
MongoDB Array Update Operators
These operators modify values inside an array field, rather than replacing the whole array.
| Operator | Description |
|---|---|
$ |
Placeholder for the first array element that matched the query |
$[] |
Placeholder for every element in the array |
$[<identifier>] |
Placeholder for elements matching an arrayFilters condition |
$addToSet |
Adds a value only if it isn't already present |
$pop |
Removes the first or last element |
$pull |
Removes all elements matching a condition |
$pullAll |
Removes all elements matching a list of exact values |
$push |
Appends a value to the array |
The Positional $ Operator
Updates the first array element that matched your query condition, without you needing to know its index.
db.employees.updateOne(
{ empid: 202, deptwork: 2 },
{ $set: { "deptwork.$": 4 } }
)
// replaces the "2" inside deptwork with "4"
If there are multiple matching elements, only the first one is changed.
$[] — Update Every Element
db.employees.updateOne(
{ empid: 202 },
{ $inc: { "deptwork.$[]": 2 } }
)
// adds 2 to every number in the deptwork array
$[] — Update Filtered Elements
Combine with arrayFilters to update only elements that match a condition — and unlike the plain $, this updates all matches, not just the first.
db.employees.updateOne(
{ empid: 202 },
{ $set: { "deptwork.$[ele]": 8 } },
{ arrayFilters: [{ "ele": 6 }] }
)
// every "6" in deptwork becomes "8"
$addToSet — Add Without Duplicates
db.employees.updateOne({ empid: 202 }, { $addToSet: { deptwork: 10 } })
// inserts 10
db.employees.updateOne({ empid: 202 }, { $addToSet: { deptwork: 10 } })
// no-op — 10 is already there
Passing a plain array inserts the whole array as one element — use $each to add multiple individual values:
db.employees.updateOne(
{ empid: 204 },
{ $addToSet: { deptwork: { $each: [1, 2, 3] } } }
)
$pop — Remove First or Last Element
db.employees.updateOne({ empid: 202 }, { $pop: { deptwork: 1 } }) // removes the LAST element
db.employees.updateOne({ empid: 202 }, { $pop: { deptwork: -1 } }) // removes the FIRST element
$pull — Remove Matching Elements
db.employees.updateOne({ empid: 204 }, { $pull: { deptwork: 3 } })
// removes the value 3 wherever it appears
db.employees.updateOne({ empid: 204 }, { $pull: { deptwork: { $in: [1, 2] } } })
// removes 1 AND 2
$pullAll — Remove an Exact List of Values
db.employees.updateOne({ empid: 202 }, { $pullAll: { deptwork: [10, 11] } })
$push — Append to an Array
db.employees.updateOne({ empid: 202 }, { $push: { deptwork: 11 } })
Unlike $addToSet, $push doesn't check for duplicates — pushing the same value twice adds it twice.
$push Modifiers: $each, $position, $slice, $sort
// add multiple values at once
db.employees.updateOne({ empid: 202 }, { $push: { deptwork: { $each: [3, 4] } } })
// insert at a specific index instead of the end
db.employees.updateOne(
{ empid: 202 },
{ $push: { deptwork: { $each: [10, 11], $position: 2 } } }
)
// keep only the last 4 elements after pushing
db.employees.updateOne(
{ empid: 204 },
{ $push: { deptwork: { $each: [10, 11, 12], $slice: -4 } } }
)
// push and re-sort the array (ascending or descending)
db.employees.updateOne(
{ empid: 204 },
{ $push: { deptwork: { $each: [30], $sort: 1 } } }
)
// $each: [] with $sort lets you re-sort WITHOUT pushing anything new
db.employees.updateOne(
{ empid: 202 },
{ $push: { deptwork: { $each: [], $sort: -1 } } }
)
Common Errors & Troubleshooting
$pushing a value you meant to$addToSet—$pushnever checks for duplicates; if you actually wanted "add only if not already present," you need$addToSet, not$push.$[<identifier>]without a matchingarrayFilters— the filtered positional operator requires a correspondingarrayFiltersoption in the same call; omitting it (or misspelling the identifier) throws an error.- The positional
$operator matching the wrong document when the array condition also filters documents —$always refers to the first array element that matched the query's array condition on that document, which can be surprising if the query condition and the update path don't line up as expected.
Key Takeaways
$pushallows duplicates;$addToSetnever does.- Use
$eachwhenever you need to add or remove several array values in one call. - The positional
$updates the first match;$[]updates all elements;$[<id>]+arrayFiltersupdates a filtered subset.