Skip to main content

MongoDB updateMany

Introduction

In MongoDB, the ability to modify existing data is crucial for maintaining up-to-date information in your database. While updateOne() allows you to update a single document, real-world applications often require updating multiple documents simultaneously. This is where the updateMany() method becomes essential.

The updateMany() operation allows you to update all documents in a collection that match specified criteria. This powerful method can save you significant time and effort compared to updating documents one by one, especially in large collections.

Basic Syntax

The basic syntax for the updateMany() method is:

javascript
db.collection.updateMany(
<filter>,
<update>,
{
upsert: <boolean>,
writeConcern: <document>,
collation: <document>,
arrayFilters: <array>,
hint: <document|string>
}
)

Where:

  • filter: The selection criteria for the documents to update.
  • update: The modifications to apply to the matching documents.
  • options: Optional settings for the update operation.

Basic Example

Let's start with a simple example. Imagine we have a collection of products and we need to add a "sale" flag to all electronics products:

javascript
// Our collection has these products
[
{ name: "Laptop", category: "electronics", price: 899 },
{ name: "Smartphone", category: "electronics", price: 699 },
{ name: "Coffee Maker", category: "appliances", price: 49 },
{ name: "Headphones", category: "electronics", price: 149 }
]

// Update all electronics to add a 'sale' field
db.products.updateMany(
{ category: "electronics" },
{ $set: { onSale: true } }
)

// Result
{
"acknowledged": true,
"matchedCount": 3,
"modifiedCount": 3
}

After this operation, our collection would look like:

javascript
[
{ name: "Laptop", category: "electronics", price: 899, onSale: true },
{ name: "Smartphone", category: "electronics", price: 699, onSale: true },
{ name: "Coffee Maker", category: "appliances", price: 49 },
{ name: "Headphones", category: "electronics", price: 149, onSale: true }
]

Update Operators

MongoDB provides several update operators that allow you to perform different types of modifications:

$set Operator

The $set operator replaces the value of a field with the specified value:

javascript
// Set inventory status to 'low' for all products with quantity less than 10
db.products.updateMany(
{ quantity: { $lt: 10 } },
{ $set: { inventoryStatus: "low" } }
)

$inc Operator

The $inc operator increments a field by a specified value:

javascript
// Apply 10% price increase to all products
db.products.updateMany(
{}, // empty filter matches all documents
{ $mul: { price: 1.1 } }
)

$unset Operator

The $unset operator removes a field from documents:

javascript
// Remove the 'seasonal' field from all products
db.products.updateMany(
{},
{ $unset: { seasonal: "" } }
)

Array Update Operators

MongoDB also provides operators to update arrays:

$push

Adds an element to an array:

javascript
// Add a new tag to all electronics products
db.products.updateMany(
{ category: "electronics" },
{ $push: { tags: "sale2023" } }
)

$pull

Removes elements from an array that match specific conditions:

javascript
// Remove the 'discontinued' tag from all products
db.products.updateMany(
{},
{ $pull: { tags: "discontinued" } }
)

Multiple Update Operations

You can perform multiple update operations in a single updateMany() call:

javascript
// Update price and add a tag for all products in 'clothing' category
db.products.updateMany(
{ category: "clothing" },
{
$mul: { price: 0.9 }, // 10% discount
$push: { tags: "summer-sale" },
$set: { discounted: true }
}
)

The upsert Option

The upsert option, when set to true, creates a new document if no documents match the filter:

javascript
// Update rating for "Wireless Earbuds" or create it if it doesn't exist
db.products.updateMany(
{ name: "Wireless Earbuds" },
{ $set: { rating: 4.7, category: "electronics" } },
{ upsert: true }
)

Real-World Applications

Example 1: Applying Price Adjustments

A common scenario is when you need to apply price changes based on certain conditions:

javascript
// Apply 15% discount to all electronics products with price over $500
db.products.updateMany(
{
category: "electronics",
price: { $gt: 500 }
},
{
$mul: { price: 0.85 }, // multiply price by 0.85 (15% discount)
$set: { discounted: true, discountApplied: "15%" }
}
)

Example 2: User Data Updates

When your application undergoes changes that require updating multiple user profiles:

javascript
// Update the privacy settings for all users
db.users.updateMany(
{},
{
$set: {
privacySettings: {
dataSharing: false,
marketingEmails: false
},
privacyPolicyAccepted: true
}
}
)

Example 3: Data Correction

When you discover data quality issues:

javascript
// Fix typo in 'catagory' field and convert it to proper 'category' field
db.products.updateMany(
{ catagory: { $exists: true } },
{
$set: { category: "$catagory" },
$unset: { catagory: "" }
}
)

Update Acknowledgement

The updateMany() method returns a document with information about the update operation:

javascript
{
"acknowledged": true, // operation was acknowledged by the server
"matchedCount": 5, // number of documents that matched the filter
"modifiedCount": 5 // number of documents that were modified
}

If upsert: true and a new document is created, the result also includes an upsertedId field.

Best Practices

  1. Use specific filters: Always try to be as specific as possible with your filter to avoid unintended updates.

  2. Test updates first: Before running an update on your production database, test it on a development environment or use MongoDB's query planner to see which documents will be affected.

  3. Consider performance: Large update operations can impact database performance. Consider running updates during off-peak hours.

  4. Use atomic operators: MongoDB's atomic update operators ensure consistency even when multiple operations happen simultaneously.

  5. Use projections: When working with large documents, use projections in your queries to minimize the amount of data transferred.

javascript
// Get only names of all updated products
const updatedProducts = db.products.find(
{ category: "electronics", onSale: true },
{ name: 1, _id: 0 }
).toArray();

Common Pitfalls

Replacing vs. Updating

Be careful not to accidentally replace documents when you intend to update fields:

javascript
// INCORRECT - This replaces the entire document with just { status: "active" }
db.users.updateMany(
{ lastLogin: { $lt: new Date("2023-01-01") } },
{ status: "inactive" } // missing $set
)

// CORRECT - This only updates the status field
db.users.updateMany(
{ lastLogin: { $lt: new Date("2023-01-01") } },
{ $set: { status: "inactive" } }
)

Performance Considerations

Updates that affect many documents can take a long time and consume significant resources. Consider using batch operations for very large collections:

javascript
// Process in batches using multiple targeted updates instead of one large update
db.products.updateMany(
{ category: "books", price: { $lt: 20 } },
{ $set: { section: "budget-books" } }
)

db.products.updateMany(
{ category: "books", price: { $gte: 20, $lt: 50 } },
{ $set: { section: "standard-books" } }
)

db.products.updateMany(
{ category: "books", price: { $gte: 50 } },
{ $set: { section: "premium-books" } }
)

Summary

The updateMany() method is a powerful tool for modifying multiple documents in MongoDB. Key points to remember:

  • Use updateMany() to update all documents matching a filter criteria
  • Apply update operators like $set, $inc, $push, etc. to modify specific fields
  • The method returns information about how many documents matched and were modified
  • The upsert option allows creating new documents if none match the filter
  • Always use $set and other update operators to avoid replacing entire documents

Whether you're applying bulk updates, correcting data issues, or implementing new features across your database, updateMany() provides an efficient way to keep your data current and consistent.

Exercises

  1. Create a collection named inventory with various products having quantity, price, and category fields. Write an updateMany() operation to add a reorder field set to true for all items where quantity is less than 10.

  2. Write an update operation that gives a 20% discount to all products in the clothing category and adds a saleInfo object containing { startDate: <current date>, endDate: <30 days from now> }.

  3. Create a collection of user documents with lastActive timestamps. Write an updateMany() operation that marks users as inactive if they haven't been active in the last 90 days.

Additional Resources



If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)