使用另一个字段的值更新 MongoDB 字段 [英] Update MongoDB field using value of another field

查看:53
本文介绍了使用另一个字段的值更新 MongoDB 字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 MongoDB 中,是否可以使用来自另一个字段的值来更新字段的值?等效的 SQL 将类似于:

In MongoDB, is it possible to update the value of a field using the value from another field? The equivalent SQL would be something like:

UPDATE Person SET Name = FirstName + ' ' + LastName

MongoDB 伪代码为:

And the MongoDB pseudo-code would be:

db.person.update( {}, { $set : { name : firstName + ' ' + lastName } );

推荐答案

最好的方法是在 4.2+ 版本中,它允许在 update 文档和 中使用聚合管道="https://docs.mongodb.com/master/reference/method/db.collection.updateOne/#update-with-aggregation-pipeline" rel="nofollow noreferrer">updateOne, updateManyupdate 收集方法.请注意,后者在大多数语言驱动程序中已被弃用.

The best way to do this is in version 4.2+ which allows using of aggregation pipeline in the update document and the updateOne, updateMany or update collection methods. Note that the latter has been deprecated in most if not all languages drivers.

4.2 版还引入了 $set 管道阶段运算符,它是 $addFields 的别名.我将在这里使用 $set,因为它映射我们正在努力实现的目标.

Version 4.2 also introduced the $set pipeline stage operator which is an alias for $addFields. I will use $set here as it maps with what we are trying to achieve.

db.collection.<update method>(
    {},
    [
        {"$set": {"name": { "$concat": ["$firstName", " ", "$lastName"]}}}
    ]
)

请注意,该方法的第二个参数中的方括号定义了聚合管道而不是普通的更新文档.使用普通文档将无法正常工作.

Note that square brackets in the second argument to the method which defines an aggregation pipeline instead of a plain update document. Using a plain document will not work correctly.

在 3.4+ 中,您可以使用 $addFields$out 聚合管道运算符.

In 3.4+ you can use $addFields and the $out aggregation pipeline operators.

db.collection.aggregate(
    [
        { "$addFields": { 
            "name": { "$concat": [ "$firstName", " ", "$lastName" ] } 
        }},
        { "$out": "collection" }
    ]
)

请注意,这不会更新您的集合,而是替换现有集合或创建一个新集合.也适用于需要类型转换"的更新操作您将需要客户端处理, 并且根据操作,您可能需要使用 find() 方法而不是 .aggreate() 方法.

Note that this does not update your collection but instead replaces the existing collection or creates a new one. Also for update operations that require "typecasting" you will need client-side processing, and depending on the operation, you may need to use the find() method instead of the .aggreate() method.

我们这样做的方式是通过 $project 我们的文档并使用 $concat 字符串聚合运算符返回连接的字符串.从那里,您然后迭代 cursor 并使用 $set 更新操作符,使用批量操作将新字段添加到您的文档中,以实现最高效率.

The way we do this is by $projecting our documents and using the $concat string aggregation operator to return the concatenated string. From there, you then iterate the cursor and use the $set update operator to add the new field to your documents using bulk operations for maximum efficiency.

var cursor = db.collection.aggregate([ 
    { "$project":  { 
        "name": { "$concat": [ "$firstName", " ", "$lastName" ] } 
    }}
])

MongoDB 3.2 或更新版本

由此,您需要使用bulkWrite 方法.

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

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

MongoDB 2.6 和 3.0

从这个版本开始,你需要使用现已弃用的批量 API 及其相关方法.

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

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

// clean up queues
if(count > 0) {
    bulk.execute();
}

MongoDB 2.4

cursor["result"].forEach(function(document) {
    db.collection.update(
        { "_id": document._id }, 
        { "$set": { "name": document.name } }
    );
})

这篇关于使用另一个字段的值更新 MongoDB 字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆