项目场景
今日的工作中有个需求是按照条件修改MongoDB集合中某个字段的值。之前都是用kettle或者代码处理;但是对于短频、偶尔的修改,上述方式实在是浪费时间。所以研究了下如何通过写MongoDB的 shell去实现。
代码呈现
在做语法说明之前,先将已完成的代码呈现。
db.TEST.find({"NAME":"华为"}).forEach(function(doc){
db.TEST.update({"_id":doc._id},{"$set":{"NAME":"小米"}},false,true)
}
)
语法提炼
上文代码,其实挺简单的,就一个知识点:MongoDB的 forEach
方法;下面和大家分享下这个方法。
该方法的标准语法如下
<cursor>.forEach( function(resultset){...} )
- <cursor>
其中<cursor>表示游标,即查询结果集,对应到MongoDB数据库中就是 db.collection.find()或者 db.collection.aggregate()的查询结果集;forEach方法
会对游标进行遍历。如果您之前有接触过Oracle的PLSQL中的游标,那么这个概念对您来说就更好理解了。
- function(resultset){...}
function(resultset){...} 是对前面查询出的结果集数据的处理函数。我们可以根据实际的需求,决定该函数该如何写。其中的resultset可以自己定义写,表示的就是前面的结果集数据;如果您愿意,写个function(dog)都没关系。在花括号{}内,就是我们具体想做的操作了,可以打印(谁闲得无聊会打印呢)、删除、新增、更新等。
下面再写几个例子让大家看的更清晰一些。
打印
db.TEST.find({"NAME":"华为"}).forEach(function(doc){
printjson(doc);
}
)
您前面的 db.TEST.find({"NAME":"华为"}) 查出来什么样的结果集,就打印出什么。
删除
db.TEST.find({"NAME":"华为"}).forEach(function(doc){
db.TEST.remove(doc);
}
)
方法总结
今天处理的更新数据量是100万,其实还担心这个数据量会不会对数据库性能造成影响,甚至导致数据库崩溃。但和总监沟通后,总监说5000万数据量以下都可以用此方法。
我自己也思考了下,因为是利用forEach
方法遍历,每次更新一行,所以可以不用担心数据库崩溃问题。但一百多万的数据量,花了大几个小时才更新完,所以此方法在效率上可能还是存在不足。