我正在尝试使用变量值作为列名来更新集合中的所有文档。我通过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"进行比较。本身。 知道怎么做吗?
答案 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);