iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

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…