CRUD
Upsert
Insert if missing, update if present — and the filter you must get right to avoid duplicates.
An upsert is an update that inserts when nothing matches. Same updateOne / updateMany, with { upsert: true }. One round trip instead of find-then-insert in Node (which races).
db.users.updateOne(
{ email: "rahul@example.com" },
{ $set: { city: "Pune", isActive: true } },
{ upsert: true }
){
acknowledged: true,
matchedCount: 0,
modifiedCount: 0,
upsertedCount: 1,
upsertedId: ObjectId("64a1b2c3d4e5f6a7b8c90001")
}What gets inserted
MongoDB builds the new document from the filter equality fields plus the update operators. { email: "rahul@example.com" } becomes a field on the insert. $set fields are applied. Use `$setOnInsert` for values that must exist only on create (createdAt), not on every later update.
db.users.updateOne(
{ email: "rahul@example.com" },
{
$set: { city: "Pune" },
$setOnInsert: { createdAt: ISODate("2026-08-20"), role: "developer" }
},
{ upsert: true }
)The filter must uniquely identify the document you want. Upserting on { city: "Bangalore" } can insert a second user every time no document is matched the way you expected — or update an arbitrary Bangalore user. Prefer a unique field (email, _id). A unique index on that field (Indexing module) makes the race safe.
Interview question
What is an upsert, and when would you use it?
An update that inserts if the filter matches nothing. I use it for idempotent 'ensure this record exists' writes — a user by email, a cart by session id — so I do not find-then-insert and race. The filter has to be unique or I will create duplicates.
Interview question
What is $setOnInsert for?
Fields applied only when the upsert inserts, not when it updates. createdAt, a default role, an initial counter. Fields that should change on every call go in $set.