使用切换案例更新集合中的多个文档 [英] Update multiple docs in a collection using switch case

查看:45
本文介绍了使用切换案例更新集合中的多个文档的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在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是星期六
  • 如果from是星期日,则
  • 设置hourlyRate = 30
  • match the jobId (that is easy)
  • set hourlyRate = 20 if from is a Weekday
  • set hourlyRate = 25 if from is a Saturday
  • set hourlyRate = 30 if from 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆