R
Rishtaara
MongoDB Fundamentals
Lesson 12 of 40Article14 min

Insert Operations

insertOne() inserts one document into a collection. MongoDB auto-generates an _id field (ObjectId) if you omit it. The method returns an InsertOneResult with acknowledged and insertedId.

insertOne() — add a single document

insertOne() inserts one document into a collection. MongoDB auto-generates an _id field (ObjectId) if you omit it. The method returns an InsertOneResult with acknowledged and insertedId.

Real-life example: insertOne is like adding one new row to a spreadsheet — you get back the row ID MongoDB assigned.

Basic insertOne
use rishtaara

const result = db.products.insertOne({
  name: "Mechanical Keyboard",
  price: 3499,
  category: "electronics",
  tags: ["mechanical", "rgb"],
  stock: 45,
  createdAt: new Date()
})

// Result object:
// {
//   acknowledged: true,
//   insertedId: ObjectId("665a1b2c3d4e5f6789012345")
// }

// Retrieve by the returned ID
db.products.findOne({ _id: result.insertedId })
insertOne with custom _id
// Use a string _id when you have a natural key
db.users.insertOne({
  _id: "user_asha_khan",
  name: "Asha Khan",
  email: "asha@school.edu",
  role: "student"
})

// Use ObjectId explicitly
db.orders.insertOne({
  _id: ObjectId(),
  orderNumber: "ORD-2024-001",
  total: 1798,
  status: "pending"
})

insertMany() — batch inserts

insertMany() accepts an array of documents and inserts them in one round trip — much faster than looping insertOne in application code.

Real-life example: insertMany is like uploading a CSV of 500 products at once instead of clicking 'Add product' five hundred times.

Use ordered: false when importing large datasets where a few duplicate _id rows should not block the rest. Use ordered: true when every row must succeed or none should.
insertMany basics
db.products.insertMany([
  { name: "USB-C Hub", price: 1299, category: "electronics", stock: 80 },
  { name: "A5 Notebook", price: 79, category: "stationery", stock: 500 },
  { name: "Blue Pen Pack", price: 49, category: "stationery", stock: 1000 },
  { name: "Desk Organizer", price: 599, category: "furniture", stock: 30 }
])

// Return value:
// {
//   acknowledged: true,
//   insertedIds: {
//     '0': ObjectId("..."),
//     '1': ObjectId("..."),
//     ...
//   }
// }
Ordered vs unordered insertMany
// ORDERED (default: ordered: true)
// Stops at first error — remaining documents are NOT inserted
db.products.insertMany([
  { _id: 1, name: "Item A", price: 100 },
  { _id: 1, name: "Duplicate ID" },  // E11000 duplicate key — stops here
  { _id: 2, name: "Item C" }         // never attempted
], { ordered: true })

// UNORDERED (ordered: false)
// Continues after errors — inserts all non-conflicting docs
db.products.insertMany([
  { _id: 10, name: "Item X", price: 200 },
  { _id: 10, name: "Duplicate" },   // fails
  { _id: 11, name: "Item Y", price: 300 }  // still inserted
], { ordered: false })

// Use unordered for bulk seed scripts where partial success is OK

Legacy insert() — avoid in new code

The old insert() method accepted one document or an array. It is deprecated in favor of insertOne and insertMany. You may see it in legacy codebases — replace it when you touch that code.

Real-life example: insert() is like an old phone charger — it still works, but the new USB-C ports (insertOne/insertMany) are clearer and safer.

Legacy vs modern
// ❌ Legacy (deprecated)
db.students.insert({ name: "Old Style", grade: 9 })
db.students.insert([{ name: "A" }, { name: "B" }])

// ✅ Modern — always use these
db.students.insertOne({ name: "Modern Style", grade: 9 })
db.students.insertMany([{ name: "A" }, { name: "B" }])

Insert pitfalls — duplicate _id and 16 MB limit

Every document needs a unique _id within its collection. Inserting a duplicate _id throws error E11000 duplicate key. Each document has a maximum size of 16 MB — store large files in GridFS instead.

Real-life example: The 16 MB limit is like a mailbox that rejects packages over a certain weight — split big attachments into GridFS chunks.

  • Always set createdAt (and updatedAt) in application code for audit trails.
  • Use insertMany with ordered: false for resilient bulk imports.
  • Never store binary blobs larger than a few MB inside a document.
  • Check write concern for critical inserts — { w: 'majority' } on replica sets.
Duplicate _id error
db.students.insertOne({ _id: "student_001", name: "Asha" })
// Success

db.students.insertOne({ _id: "student_001", name: "Duplicate" })
// MongoServerError: E11000 duplicate key error collection:
// rishtaara.students index: _id_ dup key: { _id: "student_001" }

// Fix: omit _id and let MongoDB generate one, or use upsert on update
Document size and validation failures
// 16 MB max per document — includes all field names and values
// Bad: embedding a 20 MB base64 image
// Good: store file in GridFS or S3, keep URL in document

db.students.insertOne({
  name: "Rahul",
  grade: 12,
  profilePhotoUrl: "https://cdn.rishtaara.com/photos/rahul.jpg"
})

// If collection has JSON Schema validator, invalid docs are rejected:
db.createCollection("validated_students", {
  validator: {
    $jsonSchema: {
      bsonType: "object",
      required: ["name", "grade"],
      properties: {
        name: { bsonType: "string" },
        grade: { bsonType: "int", minimum: 1, maximum: 12 }
      }
    }
  }
})

db.validated_students.insertOne({ name: "Test" })
// Fails — grade is required