🍃 MongoDB Tutorial

Update Documents in MongoDB: updateOne, updateMany & upsert

Learn how to update MongoDB documents with updateOne() and updateMany(), update nested/embedded fields, and use upsert to insert-or-update in one call.

Update Documents in MongoDB

To modify existing documents, use updateOne() or updateMany(). Both take the same two arguments: a query that selects which document(s) to update, and an update document (almost always built with operators like $set) describing the change.

updateOne()

Updates only the first document that matches the query.

db.employees.updateOne({ empid: 201 }, { $set: { city: 'Mumbai' } })
// {
//   acknowledged: true,
//   matchedCount: 1,
//   modifiedCount: 1,
//   upsertedCount: 0
// }

Updating a Nested (Embedded) Field

db.employees.updateOne(
  { 'reportinmgr.mgrid': 110 },
  { $set: { 'reportinmgr.mgrprofile': 'Project Manager' } }
)

Adding a Brand-New Field

$set also works when the field doesn't exist yet — it simply creates it.

db.employees.updateOne({ city: "Palghar" }, { $set: { doj: new Date() } })

updateMany()

Same idea, but updates every document that matches the query.

db.employees.updateMany({ city: "Palghar" }, { $set: { doj: new Date() } })
// matchedCount: 3, modifiedCount: 3

db.employees.updateMany({}, { $set: { doj: new Date() } })
// an empty query object {} matches every document in the collection

upsert — Update or Insert

upsert (update + insert) is an option you pass as the third argument. If a matching document is found, it's updated as normal. If no document matches, MongoDB inserts a brand-new one using the update data.

db.employees.updateOne(
  { empid: 202 },
  { $set: { name: "Rajan11" } },
  { upsert: true }
)
// empid 202 exists -> this just updates it (upsertedCount: 0)

db.employees.updateOne(
  { empid: 212 },
  { $set: { name: "Rajan11", email: "rajan11@gmail.com", phone: 7894586523 } },
  { upsert: true }
)
// empid 212 doesn't exist -> a new document is inserted (upsertedCount: 1)

If you have a unique index on a field (like email) and omit it from the upsert data, MongoDB may throw a duplicate-key error trying to insert null for that field — always include your unique fields in the upsert document.

Common Errors & Troubleshooting

  • Passing a plain object instead of an update operator — updateOne({empid:201}, {city:'Mumbai'}) (without $set) actually tries to replace the entire document with {city:'Mumbai'}, deleting every other field. Always wrap changes in $set (or another update operator) unless you genuinely intend a full replace.
  • matchedCount: 0 — the query didn't find any document at all; double-check the filter's field name and value type (a common cause: comparing a number field against a string value).
  • modifiedCount: 0 but matchedCount: 1 — the document was found, but the new value was identical to the existing one, so MongoDB considered nothing changed — this isn't an error.

Key Takeaways

  • updateOne() touches at most one document; updateMany() touches every match.
  • Both require an update operator like $set — you can't just pass a plain replacement object without one (that would replace the whole document).
  • { upsert: true } inserts a new document only when nothing matched the query.