HOWTO · MongoDB
How to Update Multiple Documents in MongoDB
Use MongoDB updateMany() with filters and $set to update matching documents, including embedded fields and array positions.
On this page
Use MongoDB’s updateMany() method to apply one update to every document that matches a filter. This guide uses a products collection to demonstrate updates to scalar fields, embedded documents, and array positions, then explains how to read the result.
How updateMany() Works
The db.collection.updateMany() method takes a filter, an update document, and an optional options document. It applies the update to all documents selected by the filter. The method does not change a document’s _id when using the examples here, and an update can add fields that were not previously present.
The update document in these examples uses update operators such as $set. This operator-based form is distinct from an aggregation pipeline update; pipeline support is outside this guide’s scope.
Understand Filters, Updates, and Options
The first argument, filter, selects documents using the same query-document style used by find(). For example, { price: 899 } selects documents whose price is 899; {} matches every document in the collection, so use an empty filter only when that broad scope is intended.
The second argument, update, describes the changes. An update document uses operators such as $set to change fields. The optional third argument can include upsert; its default is false. When upsert is true and no document matches the filter, MongoDB inserts a document based on the filter and update. When documents do match, the update is applied to those matches.
Use $set to assign a value to a field, creating that field when it is absent. Dot notation targets a field inside an embedded document: $set: { "specs.ram": 32 } changes ram inside specs and preserves the other fields in that embedded document. This differs from setting specs itself, which replaces the value of the whole field.
A small JavaScript model illustrates the same filter-and-set idea with plain objects; it does not call MongoDB:
const products = [
{ _id: 1, name: "xPhone", price: 799 },
{ _id: 2, name: "xTablet", price: 899 },
{ _id: 3, name: "SmartTablet", price: 899 }
];
const matched = products.filter(product => product.price === 899);
for (const product of matched) product.price = 895;
console.log(JSON.stringify(matched));
Prepare the products Collection
The following documents provide a consistent example dataset for the MongoDB shell operations below. Each document includes a price, a specs embedded document, and a storage array.
Use db.products.insertMany([...]) with these documents in a fresh products collection:
{ _id: 1, name: "xPhone", price: 799, specs: { ram: 4, screen: 6.5, cpu: 2.66 }, storage: [64, 128, 256] }{ _id: 2, name: "xTablet", price: 899, specs: { ram: 16, screen: 9.5, cpu: 3.66 }, storage: [128, 256, 512] }{ _id: 3, name: "SmartTablet", price: 899, specs: { ram: 12, screen: 9.7, cpu: 3.66 }, storage: [16, 64, 128] }{ _id: 4, name: "SmartPad", price: 699, specs: { ram: 8, screen: 9.7, cpu: 1.66 }, storage: [128, 256, 1024] }{ _id: 5, name: "SmartPhone", price: 599, specs: { ram: 4, screen: 5.7, cpu: 1.66 }, storage: [128, 256] }
The examples assume these records are present and that each operation is run against the current state of the collection. If you run the scalar update more than once, reset the sample data or adjust the filter to match its current values.
Update Matching Documents
To change the price of every product currently priced at 899, call db.products.updateMany({ price: 899 }, { $set: { price: 895 } }). The filter selects documents 2 and 3, while $set assigns 895 to each selected document’s price field.
You can verify the changed values with db.products.find({ price: 895 }, { name: 1, price: 1 }). The projection requests the product name and price so the query result is focused on the fields involved in the update. On the sample data, both matching products should be returned.
Update Embedded Documents
Dot notation lets an update target fields nested inside specs without replacing the full embedded document. For example, db.products.updateMany({ price: { $gt: 700 } }, { $set: { "specs.ram": 32, "specs.screen": 9.8, "specs.cpu": 5.66 } }) selects products 1, 2, and 3 in the sample dataset and assigns the three values inside their existing specs documents.
The filter uses price, which exists in the sample data, and the update paths use specs, matching the embedded-document field name. Verify the selected products with db.products.find({ price: { $gt: 700 } }, { name: 1, price: 1, specs: 1 }) and inspect their specs values.
Update Array Elements
MongoDB array indexes are zero-based. To change the first two positions in the storage arrays for products with _id values 1, 2, and 3, use db.products.updateMany({ _id: { $in: [1, 2, 3] } }, { $set: { "storage.0": 16, "storage.1": 32 } }). The dotted paths address positions 0 and 1; any later elements remain as they were.
Check the affected documents with db.products.find({ _id: { $in: [1, 2, 3] } }, { name: 1, storage: 1 }). This query returns the names and arrays for the same three products, making it possible to inspect the changed positions.
Read the Update Result and Options
updateMany() returns a result document. Its matchedCount reports how many documents matched the filter, and modifiedCount reports how many documents were changed. These counts can differ when a matching document already has the requested values. For an upsert that inserts a document, upsertedId identifies the inserted document; when no document is inserted, that field does not provide an inserted identifier.
Use the counts to check the scope of an operation: compare matchedCount with the filter you intended, then use a follow-up find() query to inspect the fields you changed. The result describes the update operation, while the query lets you verify the stored document values.