简体   繁体   English

如何在一个命令中使用非类似更新条件更新MongoDB中的多个文档?

[英]How do I update multiple documents in MongoDB with non similar update criteria in one command?

Consider we have a salary upgrade to all employees, where the salary increase is not fixed to all people, and it depends on some fields in the same employee document, how can I update all the salaries to mongo documents (one per employee) with one command? 考虑我们对所有员工进行薪资升级,其中薪资增加并非固定在所有员工身上,而且取决于同一员工文档中的某些字段,如何将所有工资更新为mongo文档(每个员工一个)命令?

Update 更新

Consider I have the employee id or name, and the salary upgrade, and want to update all the documents with one command 考虑我有员工ID或名称,以及工资升级,并希望用一个命令更新所有文档

Sample documents 样本文件

{ _id : "11111", salary : (metric_1/metric_2) , name : "Androw", metric_1 : 12345, metric_2 : 222, {_id:“11111”,薪水: (metric_1 / metric_2) ,姓名:“Androw”,metric_1:12345,metric_2:222,
... } ... }

{ _id : "22222", salary : (metric_1/metric_2) , name : "John", metric_1 : 999, metric_2 : 223, ... } {_id:“22222”,薪水: (metric_1 / metric_2) ,姓名:“John”,metric_1:999,metric_2:223, ... }

where metric_1 and metric_2 are random factors related to user interactions, and salary is a function of them. 其中metric_1和metric_2是与用户互动相关的随机因素,而工资是它们的函数。

The below command work great, and can do the required operation as needed, considering you have a list of users' ids or names you want to update (may be all) 以下命令工作得很好,并且可以根据需要执行所需的操作,考虑到您有一个用户ID或要更新的名称列表(可能全部)

db.salaries.aggregate( [ {$match : { _id:{$in:[ObjectId("563e1d9d04aa90562201fd5f"),ObjectId("564657f88f71450300e1fe0b")]}  } } , {$project: { rating: {$divide:["$metric_1","$metric_2"]} } } , {$out:"new_salaries"} ] )

The downside of the above command is that you have to have a new collection to insert the new updated fields, and if name the existing collection (salaries in this case), it will delete all the existing fields and just add the newly computed documents, which is unsafe to do, since other operations might have occurred during the new salaries computation. 上述命令的缺点是你必须有一个新的集合来插入新的更新字段,如果命名现有的集合(在这种情况下是工资),它将删除所有现有的字段,只需添加新计算的文档,这是不安全的,因为在新的工资计算期间可能发生了其他操作。

Better approach 更好的方法

A better thing to do is to combine the aggregation pipelining with mongo's bulk operations to do batch update to our exiting collection. 更好的办法是将聚合流水线与mongo的批量操作结合起来,对我们现有的集合进行批量更新。 This way: 这条路:

var salaries_to_update = db.salaries.aggregate( [ {$match : { _id:{$in:[ObjectId("563e1d9d04aa90562201fd5f"),ObjectId("564657f88f71450300e1fe0b")]}  } } , {$project: { rating: {$divide:["$metric_1","$metric_2"]} } } ] )

Then we do bulk update operation, which does batch of updates at once without a lot of processing and traffic headache back and forth. 然后我们进行批量更新操作,它会立即进行批量更新,而无需来回处理大量处理和流量问题。

var bulk = db.salaries.initializeUnorderedBulkOp()

salaries_to_update.forEach(salary){
    bulk.find( _id: salary._id).updateOne({$set:{salary:salary.salary}})
}

bulk.execute()

Ordered bulk operations are executed in an order (thus the name), halting when there's an error. 有序批量操作按顺序执行(因此名称),在出现错误时暂停。

Unordered bulk operations are executed in no particular order (potentially in parallel) and these operations do not stop when an error occurs. 无序批量操作不按特定顺序执行(可能并行执行),并且在发生错误时这些操作不会停止。

Thus, we use unordered bulk update here. 因此,我们在这里使用无序批量更新。

That's all 就这样

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM