Inserting Documents
1. Inserting Single Document
| Method | Returns |
| insertOne(doc) | { acknowledged, insertedId } |
| insertOne(doc, {writeConcern}) | Same with custom w |
Example: Insert with explicit _id
const result = await db.users.insertOne({
_id: new ObjectId(),
email: "alice@example.com",
createdAt: new Date(),
});
console.log(result.insertedId);
2. Inserting Multiple Documents
| Method | Description |
| insertMany(docs) | Bulk insert, default ordered |
| {ordered: false} | Continue on errors |
| Batch size | Server-limited to 100k docs / 48MB per batch |
const r = await db.events.insertMany(
[{type: "a"}, {type: "b"}, {type: "c"}],
{ ordered: false, writeConcern: { w: "majority" } }
);
console.log(r.insertedCount, r.insertedIds);
3. Using Ordered Inserts
| ordered | Behavior on error |
| true (default) | Stops at first error; remaining docs skipped |
| false | Attempts all docs; reports each error |
4. Handling Insert Errors
| Code | Meaning |
| 11000 | Duplicate key |
| 121 | Document failed validation |
| 2 | BadValue (invalid BSON) |
| 10334 | Document too large (>16MB) |
| 17280 | Key too large for index |
try { await db.users.insertOne({email: "a"}); }
catch (e) { if (e.code === 11000) console.log("duplicate", e.keyValue); }
5. Setting Write Concern
| w | Effect |
| 0 | No acknowledgment (fire-and-forget) |
| 1 (default) | Primary ack only |
| "majority" | Majority of voting members ack |
| <N> | N members ack |
| tag | Custom (e.g., DC-aware) |
| j: true | Wait for journal commit |
| wtimeout | ms to wait before failing |
6. Using _id Field
| Aspect | Detail |
| Default | Auto ObjectId if not provided |
| Allowed types | Any BSON type EXCEPT array |
| Immutable | Cannot be updated after insert |
| Unique index | Always present on _id |
| Composite | Use embedded document: {_id: {a:1,b:2}} |
7. Inserting with Upsert
| Operation | Use |
| updateOne(filter, update, {upsert: true}) | Insert if missing |
| replaceOne(filter, doc, {upsert: true}) | Replace or insert |
| findOneAndUpdate(...{upsert:true, returnDocument:"after"}) | Atomic get-or-create |
| $setOnInsert | Fields set only on insert path |
8. Using Bulk Write Operations
| Op | Description |
| insertOne | Single insert |
| updateOne / updateMany | Update |
| replaceOne | Replace doc |
| deleteOne / deleteMany | Delete |
await db.orders.bulkWrite([
{ insertOne: { document: { sku: "A", qty: 1 } } },
{ updateOne: { filter: { sku: "B" }, update: { $inc: { qty: 1 } }, upsert: true } },
{ deleteMany: { filter: { status: "cancelled" } } },
], { ordered: false });
9. Handling Duplicate Key Errors
| Strategy | Example |
| Catch & ignore | if (e.code === 11000) return existing; |
| Upsert | updateOne(..., {upsert: true}) |
| Unordered batch | insertMany(docs, {ordered: false}) |
| Inspect | e.keyPattern, e.keyValue |
10. Inserting Nested Documents
| Aspect | Detail |
| Depth limit | 100 levels |
| Size limit | Single doc ≤ 16MB |
| Query | Use dot notation: "address.zip" |
11. Using Retryable Writes
| Aspect | Detail |
| URI option | retryWrites=true (default in modern drivers) |
| Scope | Single-document writes (insertOne, updateOne, deleteOne, findAndModify) |
| Trigger | Network errors, primary stepdown |
| Retries | Exactly one retry, server-deduped via session+txnNumber |
| Not retried | updateMany, deleteMany, bulkWrite (with multi) |