使用 $toLower 更新 MongoDB 集合
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9423932/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Update MongoDB collection using $toLower
提问by sveatch42
I have an existing MongoDB collection containing user names. The user names contain both lower case and upper case letters.
我有一个包含用户名的现有 MongoDB 集合。用户名包含小写和大写字母。
I want to update all the user names so they only contain lower case letters.
我想更新所有用户名,以便它们只包含小写字母。
I have tried this script, but it didn't work
我试过这个脚本,但没有用
db.myCollection.find().forEach(
function(e) {
e.UserName = $toLower(e.UserName);
db.myCollection.save(e);
}
)
回答by Gates VP
MongoDB does not have a concept of $toLower
as a command. The solution is to run a big for
loop over the data and issue the updates individually.
MongoDB 没有$toLower
作为命令的概念。解决方案是对数据运行一个大for
循环并单独发布更新。
You can do this in any driver or from the shell:
您可以在任何驱动程序中或从 shell 执行此操作:
db.myCollection.find().forEach(
function(e) {
e.UserName = e.UserName.toLowerCase();
db.myCollection.save(e);
}
)
You can also replace the save with an atomic update:
您还可以使用原子更新替换保存:
db.myCollection.update({_id: e._id}, {$set: {UserName: e.UserName.toLowerCase() } })
Again, you could also do this from any of the drivers, the code will be very similar.
同样,您也可以从任何驱动程序执行此操作,代码将非常相似。
EDIT: Remon brings up a good point. The $toLower
command does exist as part of the aggregation framework, but this has nothing to do with updating. The documentation for updating is here.
编辑:雷蒙提出了一个好观点。该$toLower
命令确实作为聚合框架的一部分存在,但这与更新无关。更新文档在这里。
回答by Xavier Guihot
Starting Mongo 4.2
, db.collection.update()
can accept an aggregation pipeline, finally allowing the update of a field based on its own value:
开始Mongo 4.2
,db.collection.update()
可以接受聚合管道,最后允许根据自己的值更新字段:
// { username: "Hello World" }
db.collection.update(
{},
[{ $set: { username: { $toLower: "$username" } } }],
{ multi: true }
)
// { username: "hello world" }
The first part
{}
is the match query, filtering which documents to update (in this case all documents).The second part
[{ $set: { username: { $toLower: "$username" } } }],
is the update aggregation pipeline (note the squared brackets signifying the use of an aggregation pipeline):Don't forget
{ multi: true }
, otherwise only the first matching document will be updated.
回答by Gajen Sunthara
Very similar solution but this worked me in new mongo 3.2 Execute the following in Mongo Shell or equivalent DB tools like MongoChef!
非常相似的解决方案,但这在新的 mongo 3.2 中对我有用 在 Mongo Shell 或等效的数据库工具(如 MongoChef)中执行以下操作!
db.tag.find({hashtag :{ $exists:true}}).forEach(
function(e) {
e.hashtag = e.hashtag.toLowerCase();
db.tag.save(e);
});
回答by Srisudhir T
A little late to the party but the below answer works very well with mongo 3.4 and above First get only those records which have different case and update only those records in bulk. The performance of this query is multifold better
聚会有点晚,但下面的答案适用于 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();
回答by Lyra
Just a note to make sure the field exists for all entries in your collection. If not you will need an if statement, like the following:
请注意确保该字段存在于您的集合中的所有条目。如果不是,您将需要一个 if 语句,如下所示:
if (e.UserName) e.UserName = e.UserName.toLowerCase();
回答by pravin
With the accepted solution I know its very trivial to do the same for an array of elements, just in case
使用公认的解决方案,我知道对一组元素执行相同的操作非常简单,以防万一
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);
}
)