如何在update语句中使用变量 - MongoDB

时间:2016-12-15 15:07:23

标签: mongodb robo3t

我正在尝试使用变量值作为列名来更新集合中的所有文档。我通过robo mongo shell命令尝试这个。 代码如下:

doc=db.Symbols.findOne();
for (key in doc) 
{
db.getCollection('Symbols').update(
   { key : null },
   {
        $set: { key: ""} 
   },
   { multi: true, upsert: false }
)
    }

但这段代码似乎对我不起作用。看起来像变量" key"在运行时不替换,而不是与变量键中的值进行比较robo mongo将其与word" key"进行比较。本身。 知道怎么做吗?

1 个答案:

答案 0 :(得分:1)

您需要一种循环遍历整个集合的机制,并在每次迭代时检查文档中的每个字段是否为null,并相应地更新集合。基本方法如下:

db.Symbols.find({}).forEach(function(doc){
    var update = { "$set": { } },
        query = {};
    for (var key in doc) {
        if (doc[key] === null) {
            update["$set"][key] = "";
            query[key] = { "$exists": false }
        }            
    }
    if (Object.keys(query).length !=== 0) 
        db.Symbols.updateOne(query, update);        

});

对于非常庞大的集合,您可以利用批量API更有效地利用您的更新,批量API可以批量更新您的集合,而不是每个文档发送更新请求,从而使更新更快,更高效。以下示例使用 bulkWrite() 方法演示此内容:

var ops = [];

db.Symbols.find({}).forEach(function(doc){
    var update = { "$set": { } },
        query = {};
    for (var key in doc) {
        if (doc[key] === null) {
            update["$set"][key] = "";
            query[key] = { "$exists": false }
        }            
    }
    if (Object.keys(query).length !=== 0) {
        ops.push({
            "updateOne": {
                "filter": query,
                "update": update
            }
        });
    }


    // Send to server in batches of 500 operations only
    if (ops.length % 1000 === 0) {
        db.Symbols.bulkWrite(ops);
        ops = [];
    }
})

// Clear remaining queue
if (ops.length > 0)
    db.Symbols.bulkWrite(ops);