MongoDB:更新一个字段上的所有文档

时间:2016-10-13 07:06:09

标签: mongodb

{
    "_id" : 1,
    "users" : 2329255

},
{
    "_id" :2,
    "users" : 2638831
}

如何更新所有文档用户字段除以100。 结果将是

{
    "_id" : 1,
    "users" : 23292.55
},
{
    "_id" : 2,
    "users" : 26388.31
}

db.coll.update({}, {$set: {'users': {'$divide': ['$users', 100]}}}) ----它无法正常工作

2 个答案:

答案 0 :(得分:1)

尝试以下查询:

 db.coll.find().snapshot().forEach(
      function (e) {
       e.users = e.users/100;

        // save the updated document
        db.coll.save(e);
      }
    )

以上查询将更改/更新数据库中的数据。如果要获取具有分隔值的记录,请使用$ project:

db.coll.aggregate(
   [
     { $project: {  users: { $divide: [ "$users", 100 ] } } }
   ]
)

这不会更新数据,但会返回您想要的值。

根据您的要求使用。

答案 1 :(得分:1)

$divide 运算符仅对 aggregate() 函数有效,而不是 update() 功能。你想要做的是使用 aggregate() 方法创建一个计算字段,迭代结果 aggregate() cursor创建 bulk 更新操作,您可以在一个请求中发送到服务器,而不是发送每个更新请求结果中的每个项目。

以下示例演示了这一点:

var bulkUpdateOps = [];
db.coll.aggregate([
    { "$match": { "users": { "$exists": true } } }
    {
        "$project": {
            "computed_field": { 
                "$divide": ["$users", 100] 
            }               
        }
    }
]).forEach(function(doc){
    bulkUpdateOps.push({ 
        "updateOne": {
            "filter": { "_id": doc._id },
            "update": { "$set": { "users": doc.computed_field } }
        }
    });

    if (bulkUpdateOps.length === 500) {
        db.coll.bulkWrite(bulkUpdateOps);
        bulkUpdateOps = [];
    }
});

if (bulkUpdateOps.length > 0) db.coll.bulkWrite(bulkUpdateOps);

或者对于MongoDB 2.6.x和3.0.x版本,请使用此版本的Bulk operations

var bulk = db.coll.initializeUnorderedBulkOp(),
    counter = 0;

db.coll.aggregate([
    { "$match": { "users": { "$exists": true } } }
    {
        "$project": {
            "computed_field": { 
                "$divide": ["$users", 100] 
            }
        }
    }
]).forEach(function(doc) {
    bulk.find({ "_id": doc._id })
        .updateOne({ "$set": { "users": doc.computed_field } });

    if (counter % 500 === 0) {
        bulk.execute();
        bulk = db.coll.initializeUnorderedBulkOp();
    }
});

if (counter % 500 !== 0 ) bulk.execute();

这两种情况下的批量操作API都有助于减少服务器上的IO负载,方法是在集合中每500个文档中只发送一次请求进行处理。