使用更新操作将字段转换为数组

时间:2014-06-04 23:57:55

标签: mongodb mongodb-query

在Mongo中,如何仅使用update操作将字段转换为仅包含原始值的数组?

给出一份文件:

{
  "field": "x"
}

然后是一个或多个更新操作:

db.items.update(...)

应该导致:

{
    "field": ["x"]
}

1 个答案:

答案 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限制下将其调整为任何内容。所有更新仍然是单独执行的,但这会从整个操作中删除大量写入/确认流量,并且速度更快。