使用switch case更新集合中的多个文档

我在我的NodeJS应用程序中使用MongoDB本地驱动程序。

我在我的数据库中有一个需要更新的shifts集合。 在我的class次集合中的示例文档

 { "_id" : ObjectId("588425105560bd2ba0065fa4"), "from" : ISODate("2017-01-23T03:20:00.000Z"), "to" : ISODate("2017-01-23T06:20:00.000Z"), "jobId" : ObjectId("586efda790541421b0432897"), "hourlyRate" : 15 } { "_id" : ObjectId("588425105560bd2ba0065fa5"), "from" : ISODate("2017-01-25T03:20:00.000Z"), "to" : ISODate("2017-01-25T06:20:00.000Z"), "jobId" : ObjectId("586efda790541421b0432897"), "hourlyRate" : 15 } 

我需要做的是以下 –

更新符合条件的所有文档的hourlyRate

  • 匹配jobId(很简单)
  • 设置hourlyRate = 20如果from是Weekday
  • 设置hourlyRate = 25如果from星期六开始
  • 设置hourlyRate = 30如果from星期天开始

我想尽可能在​​单个查询中完成。

我的解决scheme迄今为止

使用开关大小写,并使用date聚合函数中的$dayOfWeek确定datetypes。 但是,我无法将交换机与updateMany结合使用。

任何帮助,将不胜感激。

您可以使用特殊的运算符来运行以下聚合pipe道,如$switch ,这是MongoDB Server 3.4及更高版本中的新增function:

MongoDB服务器3.4

 db.collection('shifts').aggregate([ { "$match": { "jobId": ObjectId(job._id), "from": { "$gte": new Date() } } }, { "$project": { "hourlyRate": { "$switch": { "branches": [ { "case": { "$not": { "$in": [ { "$dayOfWeek": "$from" }, [1, 7] ] } }, "then": 20 }, { "case": { "$eq": [ { "$dayOfWeek": "$from" }, 7 ] }, "then": 25 }, { "case": { "$eq": [ { "$dayOfWeek": "$from" }, 1 ] }, "then": 30 } ] } } } } ], function(err, docs) { var ops = [], counter = 0; docs.forEach(function(doc) { ops.push({ "updateOne": { "filter": { "_id": doc._id }, "update": { "$set": { "hourlyRate": doc.hourlyRate } } } }); counter++; if (counter % 500 === 0) { db.collection('shifts').bulkWrite(ops, function(err, r) { // do something with result }); ops = []; } }) if (counter % 500 !== 0) { db.collection('shifts').bulkWrite(ops, function(err, r) { // do something with result } } }); 

MongoDB服务器3.2

  db.collection('shifts').aggregate([ { "$match": { "jobId": ObjectId(job._id), "from": { "$gte": new Date() } } }, { "$project": { "hourlyRate": { "$cond": [ { "$not": { "$setIsSubset": [ [{ "$dayOfWeek": "$from" }], [1, 7] ] } }, 20, { "$cond": [ { "$eq": [ { "$dayOfWeek": "$from" }, 7 ] }, 25, { "$cond": [ { "$eq": [ { "$dayOfWeek": "$from" }, 1 ] }, 30, "$hourlyRate" ] } ] } ] } } } ], function(err, docs) { var ops = [], counter = 0; docs.forEach(function(doc) { ops.push({ "updateOne": { "filter": { "_id": doc._id }, "update": { "$set": { "hourlyRate": doc.hourlyRate } } } }); counter++; if (counter % 500 === 0) { db.collection('shifts').bulkWrite(ops, function(err, r) { // do something with result }); ops = []; } }) if (counter % 500 !== 0) { db.collection('shifts').bulkWrite(ops, function(err, r) { // do something with result } } })