mongodb 使用文档中另一个字段的值更新字段

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2606657/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 11:43:36  来源:igfitidea点击:

Update field with another field's value in the document

mongodbmongodb-query

提问by firefox01

I have a collection t1with the following fields in its schema

我有一个t1在其架构中包含以下字段的集合

_id, field1, field1

I want set field2's value field1like sql:

我想要 setfield2的值,field1如 sql:

update t1 set field1=field2;

How do I do it in MongoDB?

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

回答by Jakub P.

Good and bad news here.

这里的好消息和坏消息。

Bad news is that AFAIK you can't do it with a single update() call - mongo doesn't support referring to current object in update.

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

Good news is that there are other ways to do it, e.g. you can run a forEach loop:

好消息是还有其他方法可以做到,例如您可以运行 forEach 循环:

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

You can run forEach in the admin shell ('mongo' command), or through some of the methods of your specific driver (e.g. in PHP I'd expect it to work with mongodb.execute() as described in here: http://www.php.net/manual/en/mongodb.execute.php)

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

回答by styvane

Starting from version 3.4, we can use the $addFieldsaggregation pipeline operator to this without client side processing which is the most efficient way.

从 3.4 版本开始,我们可以使用$addFields聚合管道运算符来实现这一点,而无需客户端处理,这是最有效的方法。

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


Prior to version 3.4 we need to iterate the Cursorobject and use $setoperator to add the new field with the existing "field1" value. You need to do this using "bulk" operation for maximum efficiency.

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

MongoDB 3.2 deprecates Bulk()and its associated methods,thus from 3.2 upwards you need to use the bulkWritemethod.

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);
}


From version 2.6 to 3.0 you can use the BulkAPI.

从版本 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();
}

回答by Deejay

This can be done through:

这可以通过:

db.nameOfCollection.find().forEach(
    function (elem) {
        db.nameOfCollection.update(
            {
                _id: elem._id
            },
            {
                $set: {
                    field2: elem.field1
                }
            }
        );
    }
);