Updating Nested Fields and Embedded Documents
MongoDB lets you update nested fields using dot notation. Choosing the correct update expression is important because replacing an entire embedded document can unintentionally remove sibling fields.
Update one nested field
Suppose the document is:
{
name: "Arun",
address: {
city: "Chennai",
country: "India",
postalCode: "600001"
}
}
To change only the city:
db.users.updateOne(
{ name: "Arun" },
{ $set: { "address.city": "Bengaluru" } }
);
The country and postalCode fields remain unchanged.
Replace an embedded document value
db.users.updateOne(
{ name: "Arun" },
{
$set: {
address: {
city: "Bengaluru"
}
}
}
);
This replaces the value of the address field with a document containing only city. The previous country and postalCode fields are removed from that embedded document.
This is a frequent source of accidental data loss.
Update multiple nested fields
db.users.updateOne(
{ name: "Arun" },
{
$set: {
"address.city": "Bengaluru",
"address.country": "India",
"preferences.theme": "dark"
}
}
);
The update modifies the specified nested fields without replacing their parent documents.
Creating a nested path
$set can create missing nested fields when the path can be constructed without conflicting with an incompatible existing value.
If an intermediate field exists as a scalar instead of a document, a nested update may fail. For example, attempting to set address.city when address is a string cannot be treated as an ordinary nested-document update.
Removing nested fields
db.users.updateOne(
{ name: "Arun" },
{ $unset: { "address.postalCode": "" } }
);
This removes only the nested postalCode field.
Data-modeling considerations
If nested structures are frequently updated independently or are very large, consider whether they should remain embedded or be modeled separately. The correct choice depends on consistency requirements, access patterns, and the lifecycle of the related data.
Using $set: { address: { city: "Bengaluru" } } replaces the entire address value. Use $set: { "address.city": "Bengaluru" } when only the city should change.
db.nestedUpdateDemo.insertOne({
name: "Arun",
address: {
city: "Chennai",
country: "India",
postalCode: "600001"
}
});
// Safely update only the city.
db.nestedUpdateDemo.updateOne(
{ name: "Arun" },
{ $set: { "address.city": "Bengaluru" } }
);
// Remove only the postal code.
db.nestedUpdateDemo.updateOne(
{ name: "Arun" },
{ $unset: { "address.postalCode": "" } }
);
db.nestedUpdateDemo.findOne({ name: "Arun" });- Dot notation targets individual nested fields.
- Replacing an embedded document removes unspecified sibling fields.
- $unset can remove a nested field without removing the entire parent document.
- Nested updates can fail when an intermediate path has an incompatible type.
- Data modeling should reflect how related information is accessed and updated.
A user document contains `address.city`, `address.country`, and `address.postalCode`. What happens when `$set` assigns `{ city: "Bengaluru" }` to the entire `address` field?