Updating Documents
1. Updating Single Document (updateOne())
| Param | Description |
|---|---|
| filter | Selection criteria |
| update | Operator expression OR aggregation pipeline (4.2+) |
| options | upsert, collation, hint, arrayFilters, writeConcern |
| returns | {matchedCount, modifiedCount, upsertedId} |
await db.users.updateOne({ _id: id }, { $set: { lastLogin: new Date() }, $inc: { loginCount: 1 } });
2. Updating Multiple Documents (updateMany())
| Aspect | Detail |
|---|---|
| Scope | All matching docs |
| Atomicity | Per-document; not transactional unless in session |
| Retryable? | No (multi=true ops are not retryable writes) |
3. Replacing Document
| Method | Behavior |
|---|---|
| replaceOne(filter, doc) | Replace entire doc except _id |
| Constraint | doc must not contain update operators |
| Upsert | Supported with {upsert: true} |
4. Using $set Operator
| Behavior | Detail |
|---|---|
| Sets value | Creates field if missing |
| Nested | Dot notation creates path |
| Array element | $set: {"items.0.qty": 2} |
5. Using $unset to Remove Fields
| Form | Effect |
|---|---|
{$unset: {phone: ""}} | Removes phone field |
| Value | Ignored (use "" by convention) |
| Arrays | Sets element to null; use $pull to remove |
6. Incrementing Values ($inc)
| Form | Effect |
|---|---|
{$inc: {qty: 1}} | Atomic +1 |
{$inc: {qty: -5}} | Decrement |
| Type | Numeric only; creates field if missing |
7. Multiplying Values ($mul)
| Form | Effect |
|---|---|
{$mul: {price: 1.1}} | Multiply by 1.1 |
| Missing field | Creates with value 0 |
8. Renaming Fields ($rename)
| Form | Effect |
|---|---|
{$rename: {old: "new"}} | Rename top-level or dot path |
| Conflicts | Drops target if it exists |
| Arrays | Cannot rename across array elements |
9. Using $min and $max Operators
| Operator | Effect |
|---|---|
| $min | Set only if new value is less than current |
| $max | Set only if new value is greater than current |
| Use | Atomic high/low watermark tracking |
10. Setting on Insert ($setOnInsert)
| Aspect | Detail |
|---|---|
| Active | Only when upsert results in insert |
| Use case | createdAt, default fields |
await db.users.updateOne(
{ email: "a@b.com" },
{ $set: { lastSeen: new Date() }, $setOnInsert: { createdAt: new Date(), role: "user" } },
{ upsert: true }
);
11. Using $currentDate Operator
| Form | Effect |
|---|---|
{$currentDate: {updatedAt: true}} | Sets server Date |
{$currentDate: {ts: {$type: "timestamp"}}} | Sets BSON Timestamp |
12. Using findOneAndUpdate()
| Option | Description |
|---|---|
| returnDocument | "before" (default) | "after" |
| projection | Fields to return |
| sort | Choose deterministic match |
| upsert | Insert if no match |
| arrayFilters | Conditional positional update |
13. Using findOneAndReplace()
| Aspect | Detail |
|---|---|
| Behavior | Atomic replace + return |
| Constraint | Replacement doc has no operators |
| Options | Same as findOneAndUpdate |
14. Handling Upsert Operations
| Aspect | Detail |
|---|---|
| Filter equality | Equality fields are added to inserted doc |
| $setOnInsert | Insert-only fields |
| Race conditions | Create unique index on filter fields to prevent dupes |
| Result | upsertedId populated only when insert happened |