我目前有一个遵循以下格式的集合:
{ "_id": ObjectId(...),
"name" : "Name",
"red": 0,
"blue": 0,
"yellow": 1,
"green": 0,
...}
等等(一堆颜色)。我想做的是创建一个名为的新数组colors
,其元素是那些值为1的颜色。
例如:
{ "_id": ObjectId(...),
"name" : "Name",
"colors": ["yellow"]
}
我可以在Mongo Shell上执行此操作吗?还是应该在程序中执行?我很确定我可以使用Python做到这一点,但是在尝试直接在Shell中做到这一点时遇到了困难。如果可以在shell中完成,谁能指出我正确的方向?
谢谢。
是的,它可以轻松地在shell中完成,或者基本上可以按照适用于任何语言的示例进行操作。
此处的关键是查看“颜色”字段,然后构造一条update语句,该语句将同时从文档中删除这些字段,同时对其进行测试以查看它们是否有效地包含在数组中,然后将其添加到文档中以及更新:
var bulk = db.collection.initializeOrderedBulkOp(),
count = 0;
db.collection.find().forEach(function(doc) {
doc.colors = doc.colors || [];
var update = { "$unset": {}};
Object.keys(doc).filter(function(key) {
return !/^_id|name|colors/.test(key)
}).forEach(function(key) {
update.$unset[key] = "";
if ( doc[key] == 1)
doc.colors.push(key);
});
update["$addToSet"] = { "colors": { "$each": doc.colors } };
bulk.find({ "_id": doc._id }).updateOne(update);
count++;
if ( count % 1000 == 0 ) {
bulk.execute();
bulk = db.collection.initializeOrderedBulkOp()
}
});
if ( count % 1000 != 0 )
bulk.execute();
在批量操作的使用意味着更新的批量发送,而不是一个请求,每个文件的响应,因此这将处理大量不仅仅是发出奇异的更新来回更快。
此处的主要运算符是$unset
删除现有字段并$addToSet
添加新的评估数组。两者都是通过循环构成可能颜色的文档键并排除不希望使用正则表达式过滤器修改的其他键来构建的。
还使用$addToSet
和这行:
doc.colors = doc.colors || [];
目的是确保如果任何文档已被部分转换或以其他方式被已经开始存储正确数组的代码更改所影响,则更新过程不会对它们造成不利影响或覆盖。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句