Desctiption
MongoDB's updateMany
method doesn't update any documents when used with $rename
on some fields.
Example
I try to rename the fields blog.blog_ttile
and blog.blog_cotnet
. I checked for typos, there are none.
Example model:
User: {
name,
email,
blog: {
blog_ttile,
blog_cotnet
}
}
Code:
const mongoose = require('mongoose');
const User = mongoose.model('User');
const nameChanges = {
"blog.blog_ttile": 'blog.title',
'blog.blog_cotnet': 'blog.content',
};
async function performNameChanges() {
try {
const updatedDocuments = await User.updateMany({}, { $rename: nameChanges });
console.log({ updatedDocuments });
} catch(err) {
console.error(err);
}
}
returns:
{ updatedDocuments: { ok: 0, n: 0, nModified: 0 } }
Additional details
Some fields are correctly recognized. Let's say email
in the above example. However, when I try to update the updated name, it doesn't work again. Interestingly, it still detects the original name.
Example:
Renaming email
to personal_email
works. Renaming personal_email
to email
afterwards doesn't and returns { ok: 0, n: 0, nModified: 0 }
. Calling a rename on email
a second time returns { n: <total_records>, nModified: 0, ok: 1 }
although no documents have email
anymore`.
What could be causing this?
Note:
This question applies for MongoDB without Mongoose with db.getCollection("User").updateMany
instead of User.updateMany
I tried doing the same in MongoDB. It works as expected. In your case I'm suspecting Mongoose schema to be the cause of this weird behavior. Mongoose Schema has to have the field you are looking to rename. If the field doesn't exist, it returns nModified 0. The schema will need to have both the old and the new names. Old ones to allow the migration, and the new ones for the new logic in the code.
Your return result is:
{ updatedDocuments: { ok: 0, n: 0, nModified: 0 } }
How is this possible? n=0? for query {}. It is only possible when there are no elements in your collection. n means matched count, it must be equal to total number of records in your collection.
Renaming email to personal_email works
Before first update your schema is fine. But after rename (first update), you should update your schema to :
User: {
name,
personal_email,
blog: {
blog_tile,
blog_contnet
}
}
before running the second update (renaming back to email).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With