当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《使用文档中的另一个字段值更新字段》经验,为你挑选了2个好方法。

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

_id, field1, field1

我希望set field2的值field1类似于sql:

update t1 set field1=field2;

我如何在MongoDB中执行此操作?



1> Jakub P...:

这里有好消息和坏消息.

坏消息是AFAIK你不能通过单个update()调用来做 - mongo不支持在更新中引用当前对象.

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

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

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


因为在forEach循环中调用了save(),所以光标会搞乱,并且可能会为每个文档多次调用该函数.解决方案是在foreach之前调用snapshot():db.item.find(blah).snapshot().forEach()
这样做没有原子方法吗?这个解决方案似乎不太健壮.

2> styvane..:

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

推荐阅读
郑小蒜9299_941611_G
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有