在Mongo中,如何仅使用update
操作将字段转换为仅包含原始值的数组?
给出一份文件:
{
"field": "x"
}
然后是一个或多个更新操作:
db.items.update(...)
应该导致:
{
"field": ["x"]
}
答案 0 :(得分:3)
MongoDB当前不允许您引用更新操作类型中字段的现有值。为了进行引用现有字段值的更改,您需要循环结果。但阵列转换部分很简单:
db.collection.find().forEach(function(doc) {
db.collection.update(
{ _id: doc._id },
{ "$set": { "field": [doc.field] } }
);
})
甚至更好的MongoDB 2.6中的批量更新功能:
var batch = [];
db.collection.find().forEach(function(doc) {
batch.push({
"q": { _id: doc._id },
"u": { "$set": { "field": [doc.field] } }
});
if ( batch.length % 500 == 0 ) {
db.runCommand({ "update": "collection", "updates": batch });
batch = [];
}
});
if ( batch.length > 0 )
db.runCommand({ "update": "collection", "updates": batch });
甚至使用新的Bulk API助手:
var counter = 0;
var bulk = db.collection.initializeUnorderedBulkOp();
db.collection.find().forEach(function(doc) {
bulk.find({ _id: doc._id }).update({
"$set": { "field": [doc.field] }
});
counter++;
if ( counter % 500 == 0 ) {
bulk.execute();
bulk = db.collection.initializeUnorderedBulkOp();
counter = 0;
}
});
if ( counter > 0 )
bulk.execute();
这两个最后只会将每次500项的更新发送到服务器,或者在16MB BSON限制下将其调整为任何内容。所有更新仍然是单独执行的,但这会从整个操作中删除大量写入/确认流量,并且速度更快。