insertOne / insertMany
insertOne / insertMany add documents to a collection. MongoDB auto-generates an _id if missing; you can pass your own (UUIDs, ObjectId, or strings).
insertOne, insertMany, upsert, bulk
EXAMPLE
// 1) Single document
const { insertedId } = await db.users.insertOne({
email: 'ada@example.com',
name: 'Ada Lovelace',
createdAt: new Date(),
});
// 2) Many at once — atomic per document, not per batch
const { insertedCount, insertedIds } = await db.users.insertMany([
{ email: 'a@x.com', name: 'A' },
{ email: 'b@x.com', name: 'B' },
]);
// 3) Ordered vs unordered — failure behaviour
await db.users.insertMany(batch, { ordered: false });
// ordered: false continues past errors (duplicate keys etc.) — faster
// ordered: true (default) stops at first error — safer for sequential writes
// 4) Custom _id
await db.events.insertOne({
_id: crypto.randomUUID(), // string UUID
type: 'signup',
at: new Date(),
});
// 5) Upsert via updateOne — "insert if not exists"
await db.users.updateOne(
{ email: 'ada@example.com' },
{ $setOnInsert: { createdAt: new Date() }, $set: { lastSeen: new Date() } },
{ upsert: true },
);
// 6) Detect duplicate-key errors
try {
await db.users.insertOne({ email: 'taken@example.com' });
} catch (e) {
if (e.code === 11000) {
// unique index violation
return { error: 'email exists' };
}
throw e;
}
// 7) Write concern — control durability vs speed
await db.events.insertOne(doc, {
writeConcern: { w: 'majority', j: true, wtimeout: 5000 },
});
// j: true waits for journal commit (durable)
// w: 'majority' waits for replica set quorum
// 8) Bulk write API — mix inserts, updates, deletes in one round-trip
await db.products.bulkWrite([
{ insertOne: { document: { sku: 'A-100', stock: 10 } } },
{ updateOne: { filter: { sku: 'A-099' }, update: { $inc: { stock: -1 } } } },
{ deleteOne: { filter: { sku: 'A-001' } } },
], { ordered: false });
// 9) Insert + return — Mongo doesn't have RETURNING; do an explicit findOne
const id = (await db.posts.insertOne(post)).insertedId;
const saved = await db.posts.findOne({ _id: id });
// 10) Streaming insert — pipe big files through
import { createReadStream } from 'node:fs';
import readline from 'node:readline';
const rl = readline.createInterface({ input: createReadStream('events.ndjson') });
let buf = [];
for await (const line of rl) {
buf.push(JSON.parse(line));
if (buf.length === 1000) {
await db.events.insertMany(buf, { ordered: false });
buf = [];
}
}
if (buf.length) await db.events.insertMany(buf, { ordered: false });
// 11) Unique indexes — enforce upfront
await db.users.createIndex({ email: 1 }, { unique: true });
// 12) Avoid common mistakes
// • Don't loop insertOne when you have a batch — use insertMany
// • Set unique indexes BEFORE bulk imports of dirty data
// • Pre-generate _id client-side if you need it immediately (don't wait for the response)
Why it matters
bulkWrite with ordered: false is the secret to high-throughput ingest. One round-trip, errors don’t stop the batch, and you get per-operation results back.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
db.customers.insertOne({ name: 'Ada', age: 36 });
db.customers.insertMany([
{ name: 'Linus' },
{ name: 'Grace' },
]);
Try it Yourself »
Discussion
Loading…