mongodb 7.5.0Insert Documents with MongoDB
Insert one or many MongoDB documents, inspect acknowledged write results, choose identifiers, and keep repeatable tutorial scripts safe.
Insert one document
The official Node.js driver exposes insertOne() on a collection. It accepts a document and returns an acknowledged write result containing the inserted identifier.
use("mongog_tutorial");
const inventory = db.collection("inventory");
inventory.deleteMany({ tutorialKey: "insert-one" });
const result = inventory.insertOne({
sku: "MONITOR-27",
name: "27-inch monitor",
quantity: 6,
tags: ["display", "office"],
receivedAt: ISODate(),
tutorialKey: "insert-one",
});
print("Acknowledged:", result.acknowledged);
print("Inserted id:", result.insertedId);
inventory.findOne({ _id: result.insertedId });
MongoG waits for insertOne() before assigning result, so the next line receives the resolved driver result rather than a pending Promise. Explicit await is also valid.
Insert multiple documents
Use insertMany() when the application already has a batch. The result maps each input position to its inserted _id.
inventory.deleteMany({ tutorialKey: "insert-many" });
const batch = inventory.insertMany([
{ sku: "CABLE-USBC-1", name: "USB-C cable", quantity: 30, tutorialKey: "insert-many" },
{ sku: "HUB-USB-7", name: "Seven-port hub", quantity: 12, tutorialKey: "insert-many" },
{ sku: "STAND-LAPTOP", name: "Laptop stand", quantity: 9, tutorialKey: "insert-many" },
]);
print("Inserted:", batch.insertedCount);
inventory.find({ tutorialKey: "insert-many" }).sort({ sku: 1 });
The driver sends batches efficiently, but a very large import deserves a dedicated data-transfer workflow rather than one enormous script value.
Choose identifiers deliberately
If _id is absent, the driver generates an ObjectId before sending the insert. Supplying an application identifier is valid when it is stable and unique:
inventory.insertOne({
_id: "catalog:KEYBOARD-75",
name: "75% keyboard",
quantity: 4,
tutorialKey: "custom-id",
});
The _id value cannot be changed later. A repeated _id produces a duplicate key error instead of silently overwriting the existing document.
Ordered writes and partial failure
insertMany() is ordered by default. When one insert fails, later inserts in that batch are not attempted. With { ordered: false }, the server can continue independent inserts and report the failures together. Choose intentionally: unordered execution is useful for independent bulk input, while ordered execution is easier when sequence matters.
inventory.insertMany(
[
{ _id: "demo:a", name: "First" },
{ _id: "demo:b", name: "Second" },
],
{ ordered: false },
);
Expected result
MongoG displays the write result with its operation and counts, then displays the final query as a paged document result. Re-running the tagged examples does not delete unrelated inventory.
Make repeated imports idempotent
A repeatable synchronization job often uses a stable business key and upsert instead of unconditional insert. $setOnInsert records fields that should exist only when the document is first created:
const sync = await inventory.updateOne(
{ sku: "KEYBOARD-75" },
{
$set: {
name: "75% keyboard",
quantity: 4,
syncedAt: ISODate(),
},
$setOnInsert: {
createdAt: ISODate(),
tutorialKey: "idempotent-insert",
},
},
{ upsert: true },
);
printjson({
matched: sync.matchedCount,
modified: sync.modifiedCount,
upsertedId: sync.upsertedId,
});
Create a unique index on sku when it is truly unique. Without the index, concurrent clients can both observe no match and create duplicate logical records.
Apply write concern intentionally
Write concern controls the acknowledgment requested from the deployment. The driver and connection settings normally provide an appropriate default. Override it only when the application has a documented durability or latency requirement.
An acknowledged result does not mean downstream consumers have processed the data, a backup contains it, or application validation passed. It means MongoDB met the configured acknowledgment condition for that operation.
Practice insert error handling
Create a unique index on a tutorial-only sku, insert one document, and deliberately insert the same value again inside try/catch. Print the error code and verify that the original document remains unchanged. Then use insertMany() with ordered: false and a mix of unique and duplicate values; inspect which inserts succeeded.
For mixed insert, update, replace, and delete work, prefer a bounded bulk write rather than issuing a long list of unrelated operations without result accounting.
Common mistakes
- Inserting the same logical record repeatedly without a unique key creates duplicates. Add a suitable unique index or use an upsert when that matches the domain.
- Treating
acknowledged: trueas application validation is incorrect. It means the configured write concern acknowledged the write. - Building one unbounded in-memory batch can exhaust client memory. Stream or chunk large imports.
- Catching a duplicate key error and ignoring every other error hides real operational failures.
- Retrying a timed-out insert without an idempotency key can create a duplicate when the original outcome is uncertain.
- Assuming driver-generated ObjectIds provide business uniqueness confuses record identity with domain identity.
Continue learning
Next, query documents with filters, projection, and sort. The official driver guide covers insert operations.