Insert
Inserting is how documents enter a collection. MongoDB gives you two current methods — insertOne() for a single document and insertMany() for a batch — plus bulkWrite() for mixing inserts with updates and deletes in one round-trip.
insertOne()
Inserting a single document
const result = db.users.insertOne({
name: "Alice",
email: "alice@example.com",
age: 28
})
result.acknowledged // true
result.insertedId // ObjectId("...") — auto-generated since we didn't supply _idIf the target collection doesn't exist yet, MongoDB creates it silently on the first insert — you never need a separate "create table" step.
insertMany()
Inserting multiple documents in one call
const result = db.products.insertMany([
{ sku: "WIDGET-42", name: "Blue Widget", price: 9.99 },
{ sku: "GADGET-7", name: "Red Gadget", price: 24.5 },
{ sku: "GIZMO-1", name: "Green Gizmo", price: 4.99 }
])
result.insertedCount // 3
result.insertedIds // { '0': ObjectId(...), '1': ObjectId(...), '2': ObjectId(...) }insertedIds is a map keyed by array index (as strings), not an array — access a specific one with result.insertedIds[0].Generated _id Values
Omit _id and MongoDB generates an ObjectId for you automatically before the write. Supply your own value — a string, number, or embedded document — and MongoDB uses it as-is, as long as it's unique in the collection.
Custom vs generated _id
db.users.insertOne({ name: "Bob" }) // auto _id
db.countries.insertOne({ _id: "CA", name: "Canada" }) // custom string _id
db.inventory.insertOne({ _id: { wh: "YYZ", sku: "W-1" }, qty: 5 }) // compound _idOrdered vs Unordered Inserts
By default, insertMany() is ordered: MongoDB inserts documents in array order and stops at the first error. Pass { ordered: false } to keep going and collect every error at the end.
Mode | Behavior | When to Use |
|---|---|---|
ordered: true (default) | Stops at the first failed document; later documents in the array are never attempted. | When later documents logically depend on earlier ones succeeding. |
ordered: false | Attempts every document regardless of earlier failures; errors are collected into one | Bulk imports where a few duplicate/invalid rows shouldn't block the rest. |
Unordered insert with a duplicate key
try {
db.users.insertMany(
[
{ _id: 1, name: "A" },
{ _id: 1, name: "B" }, // duplicate _id — fails
{ _id: 2, name: "C" }
],
{ ordered: false }
)
} catch (e) {
console.log(e.writeErrors.length) // 1
console.log(e.result.insertedCount) // 2 — documents 1 and 3 still went in
}Write Concern
Write concern controls how many replica set members must acknowledge a write before the driver considers it successful. It's a durability-vs-latency dial.
Setting write concern per insert
db.orders.insertOne(
{ item: "Widget", qty: 10 },
{ writeConcern: { w: "majority", wtimeout: 5000 } }
)Duplicate Key Errors
Handling E11000
try {
db.users.insertOne({ _id: "alice@example.com", name: "Alice" })
db.users.insertOne({ _id: "alice@example.com", name: "Alice Again" })
} catch (e) {
if (e.code === 11000) {
console.error("Duplicate key:", e.keyValue)
// { _id: 'alice@example.com' }
}
}_id. Check e.keyPattern to see which index triggered it before assuming it's always the primary key.Insert Performance Tips
Prefer
insertMany()over a loop ofinsertOne()calls — batching cuts network round-trips dramatically.Batch large imports into chunks of roughly 1,000–5,000 documents per call rather than one enormous array.
Use
{ ordered: false }for bulk imports where a handful of bad rows shouldn't stop the rest.Avoid unnecessary secondary indexes on a collection during a huge bulk load — each index adds write overhead per insert; build large indexes after the load when practical.
Use
bulkWrite()when a single logical operation needs a mix of inserts, updates, and deletes atomically batched together.
Example Session
test> use shop
switched to db shop
test> db.products.insertOne({ name: "Keyboard", price: 79.99 })
{
acknowledged: true,
insertedId: ObjectId('66a1c2d3e4f5a6b7c8d9e0f1')
}
test> db.products.insertMany([
... { name: "Mouse", price: 29.99 },
... { name: "Monitor", price: 349.99 }
... ])
{
acknowledged: true,
insertedIds: {
'0': ObjectId('66a1c2d3e4f5a6b7c8d9e0f2'),
'1': ObjectId('66a1c2d3e4f5a6b7c8d9e0f3')
}
}
test> db.products.countDocuments()
3db.collection.insertOne() against a collection that doesn't exist yet in a throwaway database (e.g. use scratch) to sanity-check syntax without touching real data.