bulkWrite
bulkWrite lets you send a mixed batch of inserts, updates, replaces, and deletes in one round trip. It is dramatically faster than per-document calls and supports ordered (stop on first error) or unordered (continue on error) execution. The trade-off is harder error handling — you get per-op results, not a thrown exception per failure.
Send a mixed bulk write and inspect results
EXAMPLE
const { MongoClient } = require('mongodb');
const client = new MongoClient(process.env.MONGO_URI);
await client.connect();
const orders = client.db('shop').collection('orders');
const ops = [
{ insertOne: { document: { _id: 'o1', customer: 'alice', total: 49.95, status: 'new' } } },
{ insertOne: { document: { _id: 'o2', customer: 'bob', total: 0.00, status: 'new' } } },
{ updateOne: {
filter: { _id: 'o1' },
update: { $set: { status: 'paid', paid_at: new Date() } },
} },
{ updateMany: {
filter: { status: 'new', total: { $lte: 0 } },
update: { $set: { status: 'void', voided_reason: 'zero-total' } },
} },
{ replaceOne: {
filter: { _id: 'legacy-1' },
replacement: { _id: 'legacy-1', migrated: true, migrated_at: new Date() },
upsert: true,
} },
{ deleteMany: { filter: { status: 'cancelled', created_at: { $lt: new Date('2024-01-01') } } } },
];
// ordered: false keeps going past the first error — best for independent ops
const res = await orders.bulkWrite(ops, { ordered: false });
console.log({
insertedCount: res.insertedCount,
matchedCount: res.matchedCount,
modifiedCount: res.modifiedCount,
upsertedCount: res.upsertedCount,
deletedCount: res.deletedCount,
upsertedIds: res.upsertedIds,
});
// On partial failure, the driver throws MongoBulkWriteError with the *same*
// result object on err.result, plus err.writeErrors[] describing each failed op.
try { await orders.bulkWrite(ops, { ordered: false }); }
catch (err) {
if (err.writeErrors) for (const we of err.writeErrors) {
console.error('failed op #', we.index, '->', we.errmsg);
}
}
await client.close();
Why it matters
Cap batches around 1,000 operations — Mongo splits larger batches internally and the per-batch round trip is what you are optimising. Unordered batches also unlock better parallelism on sharded clusters because each shard processes its slice without waiting for the others.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
db.customers.bulkWrite([
{ insertOne: { document: { name: 'Ada' } } },
{ updateOne: { filter: { _id }, update: { $set: { active: true } } } },
]);
Try it Yourself »
Discussion
Loading…