我有一个包含用户名的现有MongoDB集合。用户名包含小写字母和大写字母。我想更新所有用户名,因此它们只包含小写字母。 我已经尝试过这个脚本,但它无法正常工作
db.myCollection.find().forEach(
function(e) {
e.UserName = $toLower(e.UserName);
db.myCollection.save(e);
}
)
任何关于让它工作的信息都会非常感激, 斯科特
答案 0 :(得分:57)
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() } })
同样,您也可以从任何驱动程序执行此操作,代码将非常相似。
$toLower
命令确实作为聚合框架的一部分存在,但这与更新无关。更新文档为here。
答案 1 :(得分:2)
非常相似的解决方案,但这使我在新的mongo 3.2中工作 在Mongo Shell或MongoChef等等数据库工具中执行以下命令。
db.tag.find({hashtag :{ $exists:true}}).forEach(
function(e) {
e.hashtag = e.hashtag.toLowerCase();
db.tag.save(e);
});
答案 2 :(得分:1)
从Mongo 4.2
开始,db.collection.update()
可以接受聚合管道,最后允许根据其自身值更新字段:
// { username: "Hello World" }
db.collection.update(
{},
[{ $set: { username: { $toLower: "$username" } } }],
{ multi: true }
)
// { username: "hello world" }
答案 3 :(得分:0)
只是一个注释,以确保您的集合中的所有条目都存在该字段。如果不是,您将需要if语句,如下所示:
if (e.UserName) e.UserName = e.UserName.toLowerCase();
答案 4 :(得分:0)
使用已接受的解决方案,我知道对于一系列元素执行相同操作非常简单,以防万一
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);
}
)
答案 5 :(得分:0)
晚了一点,但是下面的答案在mongo 3.4及更高版本上效果很好 首先仅获取大小写不同的那些记录,然后仅批量更新这些记录。 该查询的性能要好几倍
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();