我有一个已存在的MongoDB集合包含用户名称,其中用户名包含小写字母和大写字母。
我想更新所有用户名,使它们只包含小写字母。
我尝试了这个脚本,但它没有起作用:
db.myCollection.find().forEach(
function(e) {
e.UserName = $toLower(e.UserName);
db.myCollection.save(e);
}
)
我有一个已存在的MongoDB集合包含用户名称,其中用户名包含小写字母和大写字母。
我想更新所有用户名,使它们只包含小写字母。
我尝试了这个脚本,但它没有起作用:
db.myCollection.find().forEach(
function(e) {
e.UserName = $toLower(e.UserName);
db.myCollection.save(e);
}
)
MongoDB没有$toLower
作为一个命令的概念。解决方案是运行一个大的for
循环来遍历数据并逐个发出更新命令。
您可以在任何驱动程序或shell中执行此操作:
db.myCollection.find().forEach(
function(e) {
e.UserName = e.UserName.toLowerCase();
db.myCollection.save(e);
}
)
你也可以使用原子更新来替换保存操作:
db.myCollection.update({_id: e._id}, {$set: {UserName: e.UserName.toLowerCase() } })
同样地,您也可以从任何一个驱动程序中执行此操作,代码将非常相似。
编辑:Remon指出了一个很好的观点。$toLower
命令确实作为聚合框架的一部分存在,但这与更新无关。更新文档在这里。
$set
的原子更新)了吗?我无法使其工作(没有显示错误,但实际上没有更新任何文档)。我是 JavaScript 新手,所以可能只是犯了一个初学者的错误。 - Adam Monsen从 Mongo 4.2
开始,db.collection.update()
可以接受聚合管道,从而最终允许根据其自身值更新字段:
// { username: "Hello World" }
db.collection.updateMany(
{},
[{ $set: { username: { $toLower: "$username" } } }]
)
// { username: "hello world" }
db.tag.find({hashtag :{ $exists:true}}).forEach(
function(e) {
e.hashtag = e.hashtag.toLowerCase();
db.tag.save(e);
});
使用已接受的解决方案,我知道对于一组元素做相同的操作非常简单,以防万一。
db.myCollection.find().forEach(
function(e) {
for(var i = 0; i < e.articles.length; i++) {
e.articles[i] = e.articles[i].toLowerCase();
}
db.myCollection.save(e);
}
)
var bulk = db.myCollection.initializeUnorderedBulkOp();
var count = 0
db.myCollection.find({userId:{$regex:'.*[A-Z]'}}).forEach(function(e) {
var newId = e.userId.toLowerCase();
bulk.find({_id:e._id}).updateOne({$set:{userId: newId}})
count++
if (count % 500 === 0) {
bulk.execute();
bulk = db.myCollection.initializeUnorderedBulkOp();
count = 0;
}
})
if (count > 0) bulk.execute();
请注意确保集合中所有条目都存在该字段。如果不存在,则需要使用if语句,如下所示:
if (e.UserName) e.UserName = e.UserName.toLowerCase();
if (e.UserName)
而不是
if (e.username)
? - pravin