使用$ toLower更新MongoDB集合

时间:2012-02-24 01:04:38

标签: mongodb

我有一个包含用户名的现有MongoDB集合。用户名包含小写字母和大写字母。我想更新所有用户名,因此它们只包含小写字母。 我已经尝试过这个脚本,但它无法正常工作

db.myCollection.find().forEach(
 function(e) {
 e.UserName = $toLower(e.UserName);
 db.myCollection.save(e);
 }
)

任何关于让它工作的信息都会非常感激, 斯科特

6 个答案:

答案 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" }
  • 第一部分{}是匹配查询,用于过滤要更新的文档(在本例中为所有文档)。

  • 第二部分[{ $set: { username: { $toLower: "$username" } } }],是更新聚合管道(请注意方括号表示使用聚合管道)

    • $set是新的聚合运算符,在这种情况下,它会修改"username"的值。
    • 使用$toLower,我们将"username"的值修改为小写版本。
  • 不要忘记{ multi: true },否则只会更新第一个匹配的文档。

答案 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();