MongoDB: How to update a nested field (with examples)

Updated: February 3, 2024 By: Guest Contributor Post a comment

Introduction

MongoDB is a powerful, flexible NoSQL database that offers a variety of features to work with complex data structures. One common operation is updating nested documents in a MongoDB collection. If you’re not familiar with updating nested fields, it can be a challenging task. In this tutorial, we’ll explore how to perform updates on nested fields in MongoDB, with plenty of examples to help you understand the process. Whether you’re a beginner or an experienced developer, this guide will provide the knowledge you need to work with nested documents effectively.

Understanding Nested Documents

Before diving into the update operations, it’s important to understand the structure of nested documents in MongoDB. A document in MongoDB can contain sub-documents, which are essentially documents within a document. These sub-documents can contain other sub-documents, and so on, creating a nested data structure.

Here’s a simple example of a nested document:

{
  "user_id": "JohnDoe123",
  "profile": {
    "name": "John Doe",
    "address": {
      "street": "123 Main St",
      "city": "Anytown",
      "state": "CA"
    }
  }
}

Basic Update with the $set Operator

To update a simple field at the top-level of a document, you can use the $set operator with the updateOne or updateMany function:

db.users.updateOne(
  { "user_id": "JohnDoe123" },
  { $set: { "profile.name": "Jonathan Doe" } }
);

This code updates the “name” field inside the “profile” nested document of the user with the “user_id” of “JohnDoe123”. The output confirms the successful update:

{ "acknowledged": true, "matchedCount": 1, "modifiedCount": 1 }

Advanced Updates using the $[] operator

Let’s say we have an array of addresses and we want to update a field within each embedded document. For that, we use the positional $[] operator:

db.users.updateMany(
  {},
  { $set: { "profile.addresses.$[].city": "Newtown" } }
);

This query will set the “city” field to “Newtown” for every address document in the “addresses” array. Be cautious with this operation, as it will affect all documents within the collection.

Using the positional $ operator for Array Element Updates

When you want to update a specific element within an array, you can use the positional $ operator like so:

db.users.updateOne(
  { "user_id": "JohnDoe123", "profile.addresses.city": "Anytown" },
  { $set: { "profile.addresses.$.state": "NY" } }
);

This will update only the “state” field of the array element that has the city “Anytown” under the user with the “user_id” of “JohnDoe123”. The output confirms that the operation targets only the first matching element inside the array.

Nested Arrays and the $elemMatch operator

To be more precise in selecting which array element to update, when dealing with more complex criteria, one can use the $elemMatch operator as part of the query selector:

db.users.updateOne(
  { "user_id": "JohnDoe123",
    "profile.addresses": { $elemMatch: { "city": "Anytown", "state": "CA" } } },
  { $set: { "profile.addresses.$.zip": "12345" } }
);

The $elemMatch operator allows you to specify multiple criteria for selecting an array element to update. In this case, only the element matching both city “Anytown” and state “CA” will have the “zip” field set to “12345”.

Conclusion

In this tutorial, we have gone through the process of updating nested fields in MongoDB with multiple examples. Starting with basic updates using the $set operator, to more advanced operations targeting nested arrays with the $[] and $ operators. Understanding these commands is key for anyone looking to efficiently work with nested document structures in MongoDB.