说明
在某些字段上与updateMany
一起使用时,MongoDB的$rename
方法不会更新任何文档。
示例
我尝试重命名字段blog.blog_ttile
和blog.blog_cotnet
。我检查了错别字,没有错。
Example model:
User: {
name,
email,
blog: {
blog_ttile,
blog_cotnet
}
}
代码:
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);
}
}
返回:
{ updatedDocuments: { ok: 0, n: 0, nModified: 0 } }
其他详细信息
某些字段被正确识别。让我们在上面的示例中说email
。但是,当我尝试更新更新的名称时,它将不再起作用。有趣的是,它仍然可以检测到原始名称。
示例:
将email
重命名为personal_email
是可行的。之后没有将personal_email
重命名为email
并返回{ ok: 0, n: 0, nModified: 0 }
。再次在email
上调用重命名将返回{ n: <total_records>, nModified: 0, ok: 1 }
,尽管现在没有文档包含email
。
可能是什么原因造成的?
注意:
此问题适用于不带Mongoose的db.getCollection("User").updateMany
而不是User.updateMany
的MongoDB
答案 0 :(得分:2)
我尝试在MongoDB中做同样的事情。它按预期工作。在您的情况下,我怀疑猫鼬模式是造成这种怪异行为的原因。猫鼬模式必须具有您要重命名的字段。如果该字段不存在,则返回nModified0。该模式将需要同时具有旧名称和新名称。旧版本允许迁移,新版本则允许代码中的新逻辑。
您的返回结果是:
{ updatedDocuments: { ok: 0, n: 0, nModified: 0 } }
这怎么可能? n = 0?查询{}。仅当您的集合中没有元素时才有可能。 n表示匹配的计数,它必须等于集合中的记录总数。
将电子邮件重命名为personal_email可以
在第一次更新之前,您的架构是可以的。但是在重命名(第一次更新)之后,您应该将架构更新为:
User: {
name,
personal_email,
blog: {
blog_tile,
blog_contnet
}
}
在运行第二个更新之前(重新命名为电子邮件)。
答案 1 :(得分:0)
正如在另一个答案中所说,这是因为您的猫鼬架构不包含您要重命名的字段。
在迁移发生时,您还可以在选项中指定 strict: false
,而不是保留旧字段,并且 mongoose 不会丢弃未知路径:
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 },
{
// Strict allows to update keys that do not exist anymore in the schema
strict: false,
}
).exec();
console.log({ updatedDocuments });
} catch(err) {
console.error(err);
}
}
答案 2 :(得分:0)
这样使用谢谢
import { connect } from '../database';
export const renameFileds = async () => {
const db = connect();
//let userlist = await db.UserModel.find();
const updatedDocuments = await db.UserModel.updateMany(
{},
{ $rename: { image: 'picture' } },
{
// Strict allows to update keys that do not exist anymore in the schema
strict: false,
}
).exec();
console.log({ updatedDocuments });
};
renameFileds();