Insert Documents

MongoDB · Lesson 6 of 28 7 min read Updated

Every database starts empty, so the first thing an application does is insert data: a new customer signs up, a seller lists a product, a buyer places an order. MongoDB gives you two methods for this, insertOne() and insertMany(), and both return a result that tells you exactly what was stored.

In this lesson you will add documents to the shop database, let MongoDB create IDs for you, insert many documents in one call, and learn what happens when an insert fails halfway. Start with freshly loaded data (load('shop-data.js'), then use shop).

Insert one document

insertOne() takes one document and stores it. A new customer, Vikram from Lucknow, has just registered:

MongoDB Shell
db.customers.insertOne({
  _id: 9,
  name: 'Vikram Rao',
  email: 'vikram@example.com',
  city: 'Lucknow',
  joined: ISODate('2026-10-30'),
  premium: false
})
Output
{ acknowledged: true, insertedId: 9 }

acknowledged: true means the server confirmed the write. insertedId is the _id of the new document. Because we supplied _id: 9, that is what came back.

Let MongoDB create the _id

Most of the time you do not choose _id yourself. Leave it out and mongosh (or your driver) generates an ObjectId before sending the document. A good example is product reviews, which have no natural ID of their own:

MongoDB Shell
db.reviews.insertOne({
  productId: 105,
  customerId: 2,
  stars: 4,
  comment: 'Good bass, and the battery lasts a full Pune to Mumbai trip.',
  date: ISODate('2026-10-12')
})
Output
{
  acknowledged: true,
  insertedId: ObjectId('6ae42f10c3f5e8a91d2b7a04')
}

The reviews collection did not exist; this insert created it. Your ObjectId will be different, because it contains the time you ran the command.

Keep the returned ID if your program needs it. In application code you would usually save it in a variable, for example const res = db.reviews.insertOne({...}) and then use res.insertedId.

Insert many documents at once

insertMany() takes an array of documents and sends them to the server in one round trip, which is much faster than calling insertOne() in a loop. The shop has two new products:

MongoDB Shell
db.products.insertMany([
  { _id: 111, name: 'Smart Watch', category: 'Wearables', price: 4999, stock: 30, rating: 4.1, tags: ['wearable', 'fitness'] },
  { _id: 112, name: 'Desk Lamp LED', category: 'Office', price: 899, stock: 50, rating: 4.4, tags: ['office', 'lighting'] }
])
Output
{ acknowledged: true, insertedIds: { '0': 111, '1': 112 } }

insertedIds maps each position in your array ('0', '1') to the _id that was stored. With generated IDs the result looks like this:

Output
{
  acknowledged: true,
  insertedIds: {
    '0': ObjectId('6ae42f9ec3f5e8a91d2b7a05'),
    '1': ObjectId('6ae42f9ec3f5e8a91d2b7a06')
  }
}

Notice the two ObjectIds share their first 8 hex digits (the same second) and the next 10 (the same mongosh process); only the counter at the end differs.

When an insert fails: duplicate _id

_id must be unique in a collection. Try to add another customer with _id: 1, which Aarav already has:

MongoDB Shell
db.customers.insertOne({ _id: 1, name: 'Aarav Mehta', city: 'Surat' })
Output
MongoServerError: E11000 duplicate key error collection: shop.customers index: _id_ dup key: { _id: 1 }

E11000 is MongoDB's duplicate key error. The message names the collection (shop.customers), the index that was violated (_id_, the index MongoDB builds on _id automatically) and the duplicate value. Nothing was written. You will see the same error for any field with a unique index, such as an email address, in Indexes.

Ordered and unordered inserts

What if one document in the middle of an insertMany() fails? By default inserts are ordered: MongoDB inserts the documents one by one in array order and stops at the first error. Product 104 already exists, so this batch breaks in the middle:

MongoDB Shell
db.products.insertMany([
  { _id: 113, name: 'Phone Tripod', category: 'Mobile', price: 699, stock: 40, rating: 4.0, tags: ['mobile', 'video'] },
  { _id: 104, name: 'USB-C Cable', category: 'Accessories', price: 299, stock: 10, rating: 4.1, tags: ['cable'] },
  { _id: 114, name: 'Laptop Sleeve', category: 'Accessories', price: 799, stock: 35, rating: 4.2, tags: ['laptop', 'travel'] }
])
Output
MongoBulkWriteError: E11000 duplicate key error collection: shop.products index: _id_ dup key: { _id: 104 }

mongosh follows this line with a Result: section and a Write Errors: list that give the counts and the failing document. The important facts: product 113 was inserted, 104 failed, and 114 was never tried. There is no automatic rollback of 113.

Pass { ordered: false } to make MongoDB try every document and report all failures at the end. The order of inserts is then not guaranteed, but one bad document no longer blocks the rest:

MongoDB Shell
db.products.insertMany([
  { _id: 115, name: 'Mouse Pad XL', category: 'Accessories', price: 499, stock: 90, rating: 4.3, tags: ['computer', 'gaming'] },
  { _id: 104, name: 'USB-C Cable', category: 'Accessories', price: 299, stock: 10, rating: 4.1, tags: ['cable'] },
  { _id: 116, name: 'Webcam Cover', category: 'Accessories', price: 149, stock: 200, rating: 4.6, tags: ['privacy', 'office'] }
], { ordered: false })
db.products.find({ _id: { $gt: 110 } }, { name: 1, price: 1 })
Output
MongoBulkWriteError: E11000 duplicate key error collection: shop.products index: _id_ dup key: { _id: 104 }
[
  { _id: 111, name: 'Smart Watch', price: 4999 },
  { _id: 112, name: 'Desk Lamp LED', price: 899 },
  { _id: 113, name: 'Phone Tripod', price: 699 },
  { _id: 115, name: 'Mouse Pad XL', price: 499 },
  { _id: 116, name: 'Webcam Cover', price: 149 }
]

(The find() query uses $gt, "greater than", which you will learn in Query Operators.) Products 115 and 116 both went in despite the error, while 114 from the ordered batch is missing. Use ordered inserts when later documents depend on earlier ones, and unordered inserts for large independent imports.

Common mistakes

  • Passing an array to insertOne(). insertOne([{...}, {...}]) is an error. Use insertMany() for arrays.
  • Calling insertOne() in a loop for thousands of documents. Each call is a separate round trip. Build an array and call insertMany().
  • Assuming a failed insertMany() wrote nothing. Ordered inserts keep everything before the error. Check the counts in the error, or query afterwards.
  • Typing the collection name wrong. db.prodcts.insertOne(...) creates a new, misspelled collection without complaint.

Key points

  • insertOne(doc) stores one document and returns acknowledged and insertedId.
  • insertMany([docs]) stores many in one round trip and returns insertedIds keyed by array position.
  • If you leave out _id, an ObjectId is generated for you.
  • A repeated _id (or any unique field) fails with error E11000 and that document is not stored.
  • Ordered inserts stop at the first error; { ordered: false } attempts every document.
  • Write concern controls how many servers confirm a write; majority is the default on replica sets.

Exercise

Insert three new orders for customer 8, Isha, in one call: order 1013 (one Learn Python Book, ₹649, status pending, payment UPI), order 1014 (two USB-C Cables at ₹299 each, status pending, payment card) and order 1015 (one HD Webcam, ₹1,899, status pending, payment UPI). Use the same fields as the existing orders, including items and a correct total. Make sure one bad order cannot stop the others.

Show solution
MongoDB Shell
db.orders.insertMany([
  { _id: 1013, customerId: 8, date: ISODate('2026-10-30T09:00:00Z'), status: 'pending', payment: 'UPI',
    items: [{ productId: 108, name: 'Learn Python Book', price: 649, qty: 1 }], total: 649 },
  { _id: 1014, customerId: 8, date: ISODate('2026-10-30T09:05:00Z'), status: 'pending', payment: 'card',
    items: [{ productId: 104, name: 'USB-C Cable', price: 299, qty: 2 }], total: 598 },
  { _id: 1015, customerId: 8, date: ISODate('2026-10-30T09:10:00Z'), status: 'pending', payment: 'UPI',
    items: [{ productId: 109, name: 'HD Webcam', price: 1899, qty: 1 }], total: 1899 }
], { ordered: false })

The result lists insertedIds '0': 1013, '1': 1014 and '2': 1015. { ordered: false } makes MongoDB attempt all three even if one fails, and each total is the sum of price times quantity.

Quick Quiz

1. What does insertMany() return in insertedIds?

2. An ordered insertMany() of five documents fails on the third with E11000. What is stored?

3. What does error code E11000 mean?

Learn MongoDB with a mentor

Free lessons get you started. Our Full Stack Web Development training adds real projects and code reviews from working developers.

  • Project-based learning
  • Mentor code reviews
  • Free counselling call