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