考虑我们对所有员工进行薪资升级,其中薪资增加并非固定在所有员工身上,并且取决于同一员工文档中的某些字段,如何将所有工资更新为mongo文档(每位员工一名) )用一个命令?
更新
考虑我有员工ID或姓名,以及工资升级,并想用一个命令更新所有文件
示例文档
{
_id:" 11111",
薪水:(metric_1 / metric_2),
名称:" Androw",
metric_1:12345,
metric_2:222,
... 的
}
{ _id:" 22222", 薪水:(metric_1 / metric_2), 姓名:" John", metric_1:999, metric_2:223, ... 的 }
其中metric_1和metric_2是与用户互动相关的随机因素,而薪水是他们的函数。
答案 0 :(得分:0)
以下命令工作得很好,并且可以根据需要执行所需的操作,考虑到您有一个用户列表'您要更新的ID或名称(可能全部)
db.salaries.aggregate( [ {$match : { _id:{$in:[ObjectId("563e1d9d04aa90562201fd5f"),ObjectId("564657f88f71450300e1fe0b")]} } } , {$project: { rating: {$divide:["$metric_1","$metric_2"]} } } , {$out:"new_salaries"} ] )
上述命令的缺点是你必须有一个新的集合来插入新的更新字段,如果命名现有的集合(在这种情况下是工资),它将删除所有现有的字段,只需添加新的计算文件,这是不安全的,因为在新的工资计算期间可能发生了其他操作。
更好的方法
更好的做法是将聚合流水线与mongo的批量操作结合起来,对我们现有的集合进行批量更新。这样:
var salaries_to_update = db.salaries.aggregate( [ {$match : { _id:{$in:[ObjectId("563e1d9d04aa90562201fd5f"),ObjectId("564657f88f71450300e1fe0b")]} } } , {$project: { rating: {$divide:["$metric_1","$metric_2"]} } } ] )
然后我们进行批量更新操作,它会立即进行批量更新,而不会来回处理很多处理和流量问题。
var bulk = db.salaries.initializeUnorderedBulkOp()
salaries_to_update.forEach(salary){
bulk.find( _id: salary._id).updateOne({$set:{salary:salary.salary}})
}
bulk.execute()
有序批量操作按顺序执行(因此名称), 当出现错误时停止。
执行无序批量操作 没有特定的顺序(可能并行)和这些操作 发生错误时不要停止。
因此,我们在这里使用无序批量更新。
全部