29

我有一个集合t1,其架构中有以下字段

_id, field1, field1

我想要 setfield2的值field1,如 sql:

update t1 set field1=field2;

我如何在 MongoDB 中做到这一点?

4

3 回答 3

46

这里有好消息和坏消息。

坏消息是 AFAIK 你不能用一个 update() 调用来做到这一点 - mongo 不支持在更新中引用当前对象。

好消息是还有其他方法可以做到这一点,例如你可以运行一个 forEach 循环:

db.item.find(conditions...).snapshot().forEach( function (doc) {
  doc.field1 = doc.field2; 
  db.item.save(doc); 
});

您可以在管理外壳('mongo' 命令)中运行 forEach,或者通过特定驱动程序的某些方法(例如,在 PHP 中,我希望它可以与 mongodb.execute() 一起使用,如下所述:http:/ /www.php.net/manual/en/mongodb.execute.php )

于 2010-11-23T19:47:15.957 回答
14

从 3.4 版本开始,我们可以使用$addFields聚合管道操作符,无需客户端处理,这是最有效的方式。

db.collection.aggregate(
    [
        { "$addFields": { "field2": "$field1" }},
        { "$out": "collection" }
    ]
)

在 3.4 版本之前,我们需要迭代Cursor对象并使用$set运算符添加具有现有“field1”值的新字段。您需要使用“批量”操作来实现最高效率。

MongoDB 3.2 弃用Bulk()及其相关方法,因此从 3.2 开始,您需要使用该bulkWrite方法。

var requests = [];
db.collection.find({}, { 'field1': 1 } ).snapshot().forEach(document => { 
    requests.push( { 
        'updateOne': {
            'filter': { '_id': document._id },
            'update': { '$set': { 'field2': document.field1 } }
        }
    });
    if (requests.length === 1000) {
        //Execute per 1000 operations and re-init
        db.collection.bulkWrite(requests);
        requests = [];
    }
});

if(requests.length > 0) {
    db.collection.bulkWrite(requests);
}

从版本 2.6 到 3.0,您可以使用BulkAPI。

var bulk = db.collection.initializeUnorderedBulOp();
var count = 0;

db.collection.find({}, { 'field1': 1 }).snapshot().forEach(function(document) { 
    bulk.find({ '_id': document._id }).updateOne( {
        '$set': { 'field2': document.field1 }
    });
    count++;
    if(count%1000 === 0) {
        // Excecute per 1000 operations and re-init
        bulk.execute();
        bulk = db.collection.initializeUnorderedBulkOp();
    }
})

// clean up queues
if(count > 0) {
    bulk.execute();
}
于 2016-05-17T10:54:21.930 回答
-1

这可以通过以下方式完成:

db.nameOfCollection.find().forEach(
    function (elem) {
        db.nameOfCollection.update(
            {
                _id: elem._id
            },
            {
                $set: {
                    field2: elem.field1
                }
            }
        );
    }
);
于 2015-01-28T09:57:30.817 回答