MongoDB insertMany
Introduction
In MongoDB, inserting data is one of the most fundamental operations you'll perform. While insertOne()
allows you to add a single document to a collection, there are many situations where you need to insert multiple documents at once. This is where the insertMany()
method comes in.
The insertMany()
method provides an efficient way to insert multiple documents into a collection with a single operation. This bulk insertion capability is particularly useful when you're:
- Loading initial data into a database
- Importing data from external sources
- Creating test data sets
- Performing batch operations
In this tutorial, we'll explore how to use insertMany()
effectively, understand its options, and see how it can be applied in real-world scenarios.
Basic Syntax
The basic syntax for the insertMany()
method is:
db.collection.insertMany(
[ <document 1> , <document 2>, ... ],
{
writeConcern: <document>,
ordered: <boolean>
}
)
Parameters
- Array of documents: The first parameter is an array containing the documents to insert.
- Options object (optional): The second parameter is an object that can include:
writeConcern
: Specifies the write concern levelordered
: Determines whether MongoDB should perform an ordered or unordered insert operation (defaults totrue
)
Return Value
The method returns a document containing:
acknowledged
: Boolean indicating if the operation was acknowledgedinsertedIds
: An object containing the _id values of successfully inserted documents
Basic Example
Let's start with a simple example of adding multiple users to a users
collection:
db.users.insertMany([
{
name: "John Doe",
email: "[email protected]",
age: 28,
active: true
},
{
name: "Jane Smith",
email: "[email protected]",
age: 34,
active: true
},
{
name: "Bob Johnson",
email: "[email protected]",
age: 42,
active: false
}
])
Output:
{
"acknowledged": true,
"insertedIds": {
"0": ObjectId("5f8d0c0d1c91b82e0c9cf1a1"),
"1": ObjectId("5f8d0c0d1c91b82e0c9cf1a2"),
"2": ObjectId("5f8d0c0d1c91b82e0c9cf1a3")
}
}
In this example, we inserted three user documents into the users
collection. MongoDB returned a success acknowledgment and the _id
values generated for each document.
Understanding Ordered vs. Unordered Inserts
The ordered
parameter determines how MongoDB processes the insertion of multiple documents:
Ordered Inserts (Default: ordered: true
)
- Documents are inserted in the order they appear in the array
- If an error occurs during insertion of a document, MongoDB stops processing remaining documents
- This is useful when the order of insertion matters
db.products.insertMany([
{ name: "Laptop", price: 999.99, inStock: true },
{ name: "Smartphone", price: 699.99, inStock: false },
{ name: "Headphones", price: 149.99, inStock: true }
], { ordered: true })
Unordered Inserts (ordered: false
)
- MongoDB may reorder the operations to increase performance
- If an error occurs inserting a document, MongoDB continues processing remaining documents
- This is useful for maximum throughput when order doesn't matter
db.products.insertMany([
{ name: "Keyboard", price: 59.99, inStock: true },
{ name: "Mouse", price: 29.99, inStock: true },
{ name: "Monitor", price: 299.99, inStock: false }
], { ordered: false })
Handling Duplicate Keys
When inserting multiple documents, you might encounter duplicate key errors if you're specifying custom _id
values that already exist in the collection.
Example with Custom IDs
try {
db.categories.insertMany([
{ _id: 1, name: "Electronics", featured: true },
{ _id: 2, name: "Books", featured: false },
{ _id: 3, name: "Clothing", featured: true },
{ _id: 2, name: "Sports", featured: true } // Duplicate _id: 2
]);
} catch (e) {
print(e);
}
Output (with ordered: true):
BulkWriteError({
"writeErrors": [{
"index": 3,
"code": 11000,
"errmsg": "E11000 duplicate key error collection: store.categories index: _id_ dup key: { _id: 2 }",
...
}],
"writeConcernErrors": [],
"nInserted": 3,
"nUpserted": 0,
"nMatched": 0,
"nModified": 0,
"nRemoved": 0,
"upserted": []
})
Notice that with ordered: true
(the default), MongoDB inserted the first three documents but failed on the fourth due to the duplicate _id: 2
. If we had used ordered: false
, MongoDB would have inserted documents 1 and 3, but failed on documents 2 and 4 (both with _id: 2
).
Working with Arrays of Complex Documents
MongoDB's flexible schema allows you to insert complex, nested documents:
db.orders.insertMany([
{
orderId: "ORD-001",
customer: {
name: "Alice Williams",
email: "[email protected]",
address: {
street: "123 Main St",
city: "Boston",
state: "MA",
zip: "02108"
}
},
items: [
{ product: "Laptop", qty: 1, price: 1200 },
{ product: "Mouse", qty: 1, price: 25 }
],
totalAmount: 1225,
date: new Date("2023-04-15")
},
{
orderId: "ORD-002",
customer: {
name: "Carlos Rodriguez",
email: "[email protected]",
address: {
street: "456 Oak Ave",
city: "Miami",
state: "FL",
zip: "33101"
}
},
items: [
{ product: "Headphones", qty: 1, price: 150 },
{ product: "Phone Case", qty: 2, price: 20 }
],
totalAmount: 190,
date: new Date("2023-04-16")
}
])
Real-world Example: Seeding a Product Database
Here's an example of how you might use insertMany()
to seed a product database for an e-commerce application:
// Create a function to generate products
function seedProductDatabase() {
const categories = ["Electronics", "Clothing", "Books", "Home & Kitchen"];
const products = [];
// Generate 20 sample products
for (let i = 1; i <= 20; i++) {
const categoryIndex = Math.floor(Math.random() * categories.length);
const inStock = Math.random() > 0.3; // 70% chance of being in stock
products.push({
name: `Product ${i}`,
category: categories[categoryIndex],
price: parseFloat((Math.random() * 500 + 10).toFixed(2)),
description: `This is a sample description for Product ${i}`,
inStock: inStock,
quantity: inStock ? Math.floor(Math.random() * 100) + 1 : 0,
tags: [categories[categoryIndex].toLowerCase(), i % 2 === 0 ? "featured" : "standard"],
dateAdded: new Date()
});
}
// Insert the products into the collection
return db.products.insertMany(products);
}
// Call the function and display the result
const result = seedProductDatabase();
print(`Successfully inserted ${Object.keys(result.insertedIds).length} products.`);
Error Handling with insertMany()
When working with insertMany()
in a production environment, it's important to implement proper error handling:
try {
const result = db.inventory.insertMany([
{ item: "journal", qty: 25, tags: ["blank", "red"] },
{ item: "notebook", qty: 50, tags: ["red", "blank"] },
{ item: "paper", qty: 100, tags: ["yellow", "lined"] },
{ item: "planner", qty: 75, tags: ["blank", "red"] }
]);
console.log(`${result.insertedCount} documents were inserted`);
console.log(`Inserted document IDs:`, result.insertedIds);
} catch (e) {
console.error(`Error occurred during bulk insert: ${e.message}`);
// If some documents were inserted before the error
if (e.hasOwnProperty('insertedDocs')) {
console.log(`Partial success: ${e.insertedDocs.length} documents were inserted`);
}
}
Performance Considerations
When using insertMany()
, consider these performance tips:
-
Batch Size: For very large insertions, split documents into smaller batches (e.g., 1,000 documents per batch) to avoid hitting MongoDB's maximum BSON document size limit.
-
Ordered Inserts: Use
ordered: false
for better performance when order doesn't matter, especially in sharded environments. -
Write Concern: Adjust the write concern based on your requirements for data durability vs. speed.
// Example with specific write concern
db.products.insertMany(
[
/* array of documents */
],
{
ordered: false,
writeConcern: { w: "majority", wtimeout: 5000 }
}
)
- Indexes: Be aware that inserting many documents into a collection with multiple indexes will be slower, as each index must be updated.
Summary
The insertMany()
method is a powerful tool in MongoDB for efficiently inserting multiple documents into a collection in a single operation. Key points to remember:
- Use
insertMany()
to insert multiple documents at once, passing an array of documents - Control the insertion behavior with the
ordered
option (default istrue
) - Handle potential duplicate key errors appropriately
- Implement proper error handling for production code
- Consider performance implications for very large batch insertions
By using insertMany()
effectively, you can significantly improve the performance and efficiency of your MongoDB data insertion operations compared to inserting documents one at a time.
Exercises
-
Write a script to insert 10 documents into a
students
collection with fields for name, age, grade, and subjects (as an array). -
Create a function that generates and inserts 50 random product documents with varying categories, prices, and availability.
-
Try inserting documents with some duplicate
_id
values, once withordered: true
and once withordered: false
. Observe and explain the differences in behavior. -
Write a script that handles potential errors during batch insertion and logs which documents were successfully inserted and which failed.
Additional Resources
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)