Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mongodb 获取Mongo DB中两个日期之间的工作日数_Mongodb_Date_Mongodb Query - Fatal编程技术网

Mongodb 获取Mongo DB中两个日期之间的工作日数

Mongodb 获取Mongo DB中两个日期之间的工作日数,mongodb,date,mongodb-query,Mongodb,Date,Mongodb Query,我是Mongo DB的新手。有人能帮我计算两个给定日期之间的工作日数吗 $dayOfWeek日期的值为0表示星期日,7表示星期六 但我的问题是,如何将日期从开始日期递增到结束日期,以查找工作日数 样本数据: > db.data.insert({"startDate":ISODate('2016-0101'), "endDate":ISODate('2016-02-02')}) WriteResult({ "nInserted" : 1 }) > db.data

我是Mongo DB的新手。有人能帮我计算两个给定日期之间的工作日数吗

$dayOfWeek日期的值为0表示星期日,7表示星期六

但我的问题是,如何将日期从开始日期递增到结束日期,以查找工作日数

样本数据:

 > db.data.insert({"startDate":ISODate('2016-0101'), "endDate":ISODate('2016-02-02')})  

    WriteResult({ "nInserted" : 1 })
    > db.data.find().pretty()
    { 
            "_id" : ObjectId("57c6e6a6a1e49d654caca17a"), 
            "startDate" : ISODate("2016-01-01T00:00:00Z"),
            "endDate" : ISODate("2016-02-02T00:00:00Z")
    }
现在需要查找开始日期(2016-01-01)和结束日期(2016-02-02)之间的工作日数

我可以编写一个接受开始日期和结束日期的函数,但是在该函数中如何从开始日期迭代到结束日期


请求任何帮助。

要查找两个日期之间的工作日总数,可以从总天数中减去周末总数。这里的主要问题是找出周末的总数

示例[2016-12-23;2017-01-01]

_12月23日至24日至25日____12月30日至12月31日至1月1日

__星期五、星期六、星期日、星期日、星期五、星期六、星期日

如您所见,这些日期之间有4个周末(12月24日、12月25日、12月31日和1月1日)

解决方案

以编程方式解决此问题的一种方法是使用聚合框架及其算术和日期聚合运算符

可以通过将任务拆分为2个子任务来完成:

  • 查找
    startDate
    endDate
    之间的整周数(命名为
    weeksBetween
    )。在上述示例中,
    weeksBetween=1
  • 查找
    开始日期+7*周之间
    结束日期之间的完整天数(将其命名为
    left
    ,可以是1,2,3,4,5或6)。在上述示例中,
    left=3
    (左侧天数为周五、周六和周日)。感兴趣的是剩余天数中的周末数量(将其命名为左周末,可以是0,1或2)。在上面的示例中,
    left\u weekends=2
  • 然后,周末总数为
    2*weeksBetween+left\u weeks
    。在上面的例子中,它是
    2*1+2=4

    要查找左周末,可以使用日期聚合运算符

  • 对于星期日
    dayOfWeek=1
    left_weekends=1
    如果
    left
    为1,2,3,4,5或
    left_weekends=2
    如果
    left
    为6(包括太阳和下一个周六)
  • 对于周一
    dayOfWeek=2
    left_weekends=0
    如果
    left
    为1,2,3,4或
    left_weekends=1
    如果
    left
    为5或
    left_weekends=2
    如果
    left
    为6(包括下一个周六和周日)
  • 对于星期六
    dayOfWeek=7
    left\u周末=2
    对于任何
    left
    因此,我们可以使用以下规则:

  • 如果
    余数>7
    ,则
    左=2

  • 如果
    剩余=7
    ,则周一至周六为
    左周末=1
    ,周日为
    左周末=2

  • 如果
    剩余<7
    则周一至周六的
    左周末=0
    和周日的
    左周末=1

  • 这里,
    rements=dayOfWeek+left

    查询

    db.dates.aggregate(
      {
        $project:
          {
            "daysBetween":
              {
                $add: [
                  {
                    $floor:
                      {
                        $divide: [
                          { $subtract: [ "$endDate", "$startDate" ] },
                          1000 * 60 * 60 * 24
                        ]
                      }
                  },
                  1
                ]
              },
            "startDay": { $dayOfWeek: "$startDate" },
            "endDay": { $dayOfWeek: "$endDate" }
          }
      },
      {
        $project:
          {
            "daysBetween": "$daysBetween",
            "weeksBetween": { $floor: { $divide: [ "$daysBetween", 7 ] } },
            "startDay": "$startDay",
            "remainder":
              {
                $add: [
                  { $abs: { $subtract: [ "$endDay", "$startDay" ] } },
                  "$startDay"
                ]
              }
          }
      },
      {
        $project:
          {
            "weekendsBetween":
              {
                $add: [
                  { $multiply: [ "$weeksBetween", 2 ] },
                  {
                    $cond:
                      {
                        if: { $gt: [ "$remainder", 7 ] },
                        then: 2,
                        else:
                          {
                            $cond:
                              {
                                if: { $eq: [ "$remainder", 7 ] },
                                then: 1,
                                else: 0
                              }
                          }
                      }
                  },
                  { $cond: { if: { $eq: [ "$startDay", 1 ] }, then: 1, else: 0 } }
                ]
              },
            "daysBetween": "$daysBetween"
          }
      },
      {
        $project:
          {
            "weekdaysBetween": { $subtract: [ "$daysBetween", "$weekendsBetween" ] }
          }
      }
    );
    
    样本

    { "_id": 1, "startDate": ISODate("2016-12-23T00:00:00Z"), 
                "endDate":   ISODate("2017-01-01T00:00:00Z") }
    { "_id": 2, "startDate": ISODate("2016-12-23T00:00:00Z"), 
                "endDate":   ISODate("2017-01-09T00:00:00Z") }
    { "_id": 3, "startDate": ISODate("2016-12-23T00:00:00Z"), 
                "endDate":   ISODate("2017-01-18T00:00:00Z") }  
    
    结果

    { "_id": 1, "weekdaysBetween" : 6 }
    { "_id": 2, "weekdaysBetween" : 12 }
    { "_id": 3, "weekdaysBetween" : 19 }
    

    PS延长最后一个
    $project
    阶段您还可以获得两个日期之间的总天数和周末数。在测试查询之前,不要忘记更改集合名称

    你能在需要的地方添加查询吗?@tarashypka:Updated my questionMongoDB接受简单的Javascript,因此任何现有的解决方案都应该有效:例如,看看开始日期为工作日和/或结束日期为工作日的情况如何?您想要两个日期之间包括这些日期的工作日数吗?@tarashypka是的,如果是工作日,我需要包括这些选定日期的计数。当我执行给定代码时,我得到以下错误。。。你有什么想法???错误:assert:command失败:{“errmsg”:“异常:无效运算符'$sum'”,代码:15999,“确定”:0}:聚合失败:聚合失败:在DBCollection.aggregate的Function.assert.commandWorked(src/mongo/shell/assert.js:254:5)处的doassert(src/mongo/shell/assert.js:11:14)处出现错误()(src/mongo/shell/collection.js:1278:12)at(shell):1:9在src/mongo/shell/assert.js:13如果您的MongoDB版本在3.2之前,请使用
    $add
    算术聚合运算符,而不是
    $sum
    。更新了答案。我已经厌倦了在tutorialspoint提供的编码基础上这样做。它使用的是v3.0.9。您可以使用
    db.version()进行检查
    命令。
    $sum
    运算符在v.3.0.9的
    $project
    阶段不起作用。按照我在回答中所说的和所做的,用
    $add
    运算符替换它。我用add替换了sum,并删除了$floor和$abs,因为它们在3.2中也可用。然后我得到了类似{“\u id”的输出:ObjectId(“57D011E6D6FA2C0998AE”),“weekdaysbetween”:null}即使我将开始日期指定为月开始日期,将结束日期指定为月结束日期。对此有何想法?