Say we have a users collection in MongoDB with many existing documents. One example document from the collection:
{
"_id": {
"$oid": "650b0879d96098a3f57dc950"
},
"firstName": "John",
"lastName": "Smith",
"friends": [
{
"$oid": "650b0879d96098a3f57dc951"
},
{
"$oid": "650b0879d96098a3f57dc952"
},
{
"$oid": "650b0879d96098a3f57dc953"
}
],
"_spouse": {
"$oid": "650b0879d96098a3f57dc954"
},
"address": {
"street": "16133 E Foothill Blvd",
"city": "Fontana",
"Latitude": 34.106392,
"Longitude": -117.452627
},
"images": [
{
"id": 1,
"ur": "https://dummyimage.com/700x300/000/fff"
},
{
"id": 2,
"ur": "https://dummyimage.com/700x400/000/fff"
}
],
"Active": true
}
Here, we have a couple of fields and nested fields, which we like to change because of mistakes or better naming conventions such as Address to address, _spouse to spouse, Latitude/Longitude inside the address to latitude/longitude and ur inside the image object to url.
We’ll use updateMany query with aggregation pipeline (with [...]) to update all these field names (or keys).
Below, here’s how we can do that:
Change Field Name
To fix single field Active:
db.users.updateMany(
{ Active: { $exists: true } },
[{ $set: { active: "$Active" } }, { $unset: "Active" }]
)
Note the $ sign before the current field name Active during the $set operation. It reads the current value of the existing field.
To update multiple fields at once:
db.users.updateMany(
{ Active: { $exists: true }, _spouse: { $exists: true } },
[
{ $set: { active: "$Active", spouse: "$_spouse" } },
{ $unset: ["Active", "_spouse"] }
]
)
Note that we use an array of field names to unset the old fields.
Be very careful to ensure the field to be renamed exists in the collection before copying and removing it. Passing empty
{}and running the update query mistakenly twice will wipe out the previous and new fields.
Change Nested Object Field Name
Let’s fix Latitude and Longitude inside the address object.
db.users.updateMany(
{ "address.Latitude": { $exists: true }, "address.Longitude": { $exists: true } },
[
{
$set:
{ "address.latitude": "$address.Latitude", "address.longitude": "$address.Longitude" }
},
{
$unset: ["address.Latitude", "address.Longitude"]
}
]
)
Change Object Field Name Inside Array
The images contains objects containing id and ur. As ur is misspelled, we want to rename it to url. This will be done slightly differently using $map operator, in which we replace each images element with a new object after making the conditional modification (copy ur value to url if it exists else, keep the url value as is).
db.users.updateMany(
{},
[{
$set: {
"images": {
$map: {
input: "$images",
as: "image",
in: {
id: "$$image.id",
ur: "https://google.com",
url: {
$cond: { if: { "$$image.ur": { $exists: true } }, then: "google", else: "yahoo" }
}
}
}
}
}
}]
)
The same query will work with slight modifications for changing the nested object field name within an array.
Convert Array Field to Non-array Field and Rename It
Here’s an example document from the examples collection:
{
"_id": {
"$oid": "650b0b7ed96098a3f57dc953"
},
"customers" ["123"]
}
We want to rename customers to customer and copy its first (and only) element to customer. Here’s how we do it:
db.examples.updateMany(
{ "customers": { $exists: true } },
[
{
$set: {
customer: { $arrayElemAt: ["$customers", 0] },
},
},
{
$unset: "customers",
},
]
)
See also
- Node JS Mongo Client for Atlas Data API
- Exactly Same Query Behaving Differently in Mongo Client and Mongoose
- In Node JS HTML to PDF conversion, Populate Images From URLs
- Convert HTML to PDF in Nodejs
- Nodejs Script to Add Rows in CSV File Through Terminal
- How to Run Nightmare JS On Remote Linux Server
- How to Deal With Nightmare JS Zombie Electron Processes