Inserting data, bulk writes & write concern
|
This section documents the current MongoDB 8.x server line as published at the MongoDB Server Manual, which is the reference these pages are written and verified against. No specific patch version is pinned. Some capabilities (Atlas Search, Atlas Vector Search, and parts of encryption and backup) are Atlas-only — they are linked, not documented in depth. This content was generated with the assistance of AI and should be verified against the official manual before being relied on in production, since MongoDB iterates quickly. This section’s bibliography lists the reference material consulted while preparing these pages. |
This page covers getting documents into a collection: the insertOne / insertMany / bulkWrite
methods, the result objects they return, and the write concern that decides how many nodes must acknowledge a
write before the driver considers it done. For updating and removing documents see
Updating & deleting; for reads see
Querying.
insertOne and insertMany
insertOne writes a single document; insertMany writes an array of documents in one round trip. If a
document has no _id field, the driver adds one — an ObjectId by default — before sending it.
// https://www.mongodb.com/docs/manual/tutorial/insert-documents/
db.products.insertOne({ name: "Widget", price: 9.99 })
db.products.insertMany([
{ name: "Cog", price: 2.50 },
{ name: "Sprong", price: 4.00 }
])
The result reports whether the write was acknowledged and the _id values that were stored (generated ones
included):
// insertOne
{ "acknowledged": true, "insertedId": ObjectId("665f1a2b9c4d5e6f7a8b9c0d") }
// insertMany
{
"acknowledged": true,
"insertedIds": {
"0": ObjectId("665f1a2b9c4d5e6f7a8b9c0e"),
"1": ObjectId("665f1a2b9c4d5e6f7a8b9c0f")
}
}
Ordered vs. unordered
By default insertMany is ordered: the server inserts documents in array order and stops at the first
error, leaving the remaining documents un-inserted. Passing { ordered: false } makes it unordered: the
server attempts every document, skipping only the ones that fail, and reports all errors together.
// second document duplicates an existing _id
db.products.insertMany(
[ { _id: 10, name: "A" }, { _id: 10, name: "B" }, { _id: 11, name: "C" } ],
{ ordered: false }
)
// ordered:false -> _id 10 (first) and 11 inserted, the duplicate is reported in writeErrors
// ordered:true -> only _id 10 (first) inserted, then execution halts
bulkWrite
bulkWrite sends a mixed batch of insertOne, updateOne, updateMany, deleteOne, deleteMany and
replaceOne operations in one call. It also honours ordered (default true) vs. { ordered: false },
with the same stop-on-first-error vs. attempt-all semantics as insertMany.
// https://www.mongodb.com/docs/manual/core/bulk-write-operations/
db.inventory.bulkWrite([
{ insertOne: { document: { _id: "sku-1", qty: 100 } } },
{ updateOne: { filter: { _id: "sku-2" }, update: { $inc: { qty: -3 } } } },
{ replaceOne: { filter: { _id: "sku-3" }, replacement: { _id: "sku-3", qty: 0 } } },
{ deleteOne: { filter: { _id: "sku-4" } } }
], { ordered: false })
The result tallies each operation kind and lists any generated ids:
{
"acknowledged": true,
"insertedCount": 1,
"matchedCount": 2,
"modifiedCount": 1,
"deletedCount": 1,
"upsertedCount": 0,
"insertedIds": { "0": "sku-1" },
"upsertedIds": {}
}
The update, replace and delete operations above are described in Updating & deleting.
Write concern
Write concern is the level of acknowledgement requested from the deployment. It is expressed as a document
{ w, j, wtimeout }:
-
w— how many members must acknowledge.w: 1means the primary alone;w: "majority"means a majority of voting members, so the write survives a failover. A number greater than 1 names an explicit count. -
j— iftrue, each acknowledging member must have written the operation to its on-disk journal, not merely to memory. -
wtimeout— a millisecond cap on how long to wait for thewacknowledgements; on expiry the client gets a timeout error, though the write may still have been applied.
The server default write concern is { w: "majority" } for most deployments; it can be inspected and changed
with getDefaultRWConcern / setDefaultRWConcern. Write concern can be set per operation, or per connection
via the connection string (?w=majority&journal=true).
// https://www.mongodb.com/docs/manual/reference/write-concern/
db.orders.insertOne(
{ _id: 7, total: 42 },
{ writeConcern: { w: "majority", j: true, wtimeout: 5000 } }
)
// per-connection default in the URI:
// mongodb://host1,host2,host3/shop?replicaSet=rs0&w=majority&journal=true
A "majority" acknowledgement is tied to the replica set’s oplog and majority-commit point; see
Replication for how the oplog and majority reads and writes fit
together.
The w: "majority" acknowledgement path
Retryable writes
With retryable writes enabled (the driver default; retryWrites=true in the connection string), the driver
automatically retries a write once if it fails due to a transient network error or a primary election. The
server deduplicates the retry using the operation’s statement id and the session’s transaction number, so a
single-document insertOne, updateOne, deleteOne, findAndModify or replaceOne is applied at most
once even though it was sent twice.
// https://www.mongodb.com/docs/manual/core/retryable-writes/
// mongodb://host1,host2,host3/shop?replicaSet=rs0&retryWrites=true
db.accounts.updateOne({ _id: "a-1" }, { $inc: { balance: -100 } })
// if the primary steps down mid-write, the driver retries once against the new primary;
// the $inc is not applied twice
Multi-document operations that are not inherently idempotent (updateMany, deleteMany) are not retried.
Wrapping several writes in a transaction (see
Transactions) gives all-or-nothing semantics across documents.