使用切换案例更新集合中的多个文档 [英] Update multiple docs in a collection using switch case
问题描述
我在NodeJS应用程序中使用MongoDB本机驱动程序.
I use MongoDB native driver in my NodeJS application.
我的数据库中有一个需要更新的shifts
集合.我的班次集合中的示例文档
I have a shifts
collection in my database that I need to update. Sample docs in my shifts collection
{
"_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
:
Update the hourlyRate
of all docs that meet the conditions:
- 匹配jobId(很简单)
- 如果
from
是工作日,则将hourlyRate
设置为20 - 设置
hourlyRate
= 25,如果from
是星期六
如果 - 设置
hourlyRate
= 30
from
是星期日,则- match the jobId (that is easy)
- set
hourlyRate
= 20 iffrom
is a Weekday - set
hourlyRate
= 25 iffrom
is a Saturday - set
hourlyRate
= 30 iffrom
is a Sunday
我想尽可能地在单个查询中做到这一点.
I would want to do it in a single query as far as possible.
到目前为止我的解决方案:
使用开关盒,并使用日期汇总功能中的$dayOfWeek
确定日期类型.但是,我无法将switch与updateMany
组合.
Use switch case and determine the type of day using $dayOfWeek
from Date aggregation function. However, I am not able to combine switch with updateMany
.
任何帮助将不胜感激.
推荐答案
You could run the following aggregation pipeline with special operators at your disposal like $switch
which is new in MongoDB Server 3.4 and above:
MongoDB Server 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 Server 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
}
}
})
这篇关于使用切换案例更新集合中的多个文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!