我在 NodeJS 应用程序中使用 MongoDB native 驱动程序。
我的数据库中有一个需要更新的 shifts
集合。我的轮类集合中的示例文档
{
"_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(很简单)
- 如果
from
是工作日,则设置hourlyRate
= 20 - 如果
from
是星期六,则设置hourlyRate
= 25 - 如果
from
是星期日,则设置hourlyRate
= 30
我希望尽可能在单个查询中完成此操作。
到目前为止我的解决方案:
使用 switch case 并使用日期聚合函数中的 $dayOfWeek
确定日期类型。但是,我无法将 switch 与 updateMany 结合起来。
如有任何帮助,我们将不胜感激。
最佳答案
您可以使用您可以使用的特殊运算符来运行以下聚合管道,例如 $switch
这是 MongoDB Server 3.4 及更高版本中的新增功能:
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
}
}
})
关于node.js - 使用 switch case 更新集合中的多个文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41787787/