首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >每个子文档上的MongoDB日期差异,以及最终结果中它们的总和

每个子文档上的MongoDB日期差异,以及最终结果中它们的总和
EN

Stack Overflow用户
提问于 2018-02-17 17:50:49
回答 1查看 182关注 0票数 1

我的用户集合有一个数组字段,其中包含如下所示的子文档:

代码语言:javascript
运行
复制
"training" : [ 
  {
    "id" : ObjectId("5a01867959e2868ce09fbbc5"),
    "startDate" : ISODate("2012-12-18T00:00:00.000Z"),
    "endDate" : ISODate("2015-05-31T00:00:00.000Z"),
    "inProgress" : false
  }, 
  {
    "id" : ObjectId("5a01899959e2868ce09fbbc6"),
    "startDate" : ISODate("2017-11-02T00:00:00.000Z"),
    "endDate" : ISODate("2017-11-25T00:00:00.000Z"),
    "inProgress" : false
  },
  {
    "id" : ObjectId("5a01899959e2868ce09fbbc8"),
    "startDate" : ISODate("2018-01-02T00:00:00.000Z"),
    "endDate" : null,
    "inProgress" : true
  }
],

我想要的是: 1-获取每个用户在年,月,日的总培训周期(假设第一个培训,{year: 2, month: 6, day: 12},第二个培训{year: 0, month: 0, day: 23}和最后一个培训的git差异是一个正在进行的培训,然后使用从当前日期减去,应该是{year: 0, month: 1, day: 15}) 2-然后我应该计算每个培训周期的总和作为总培训周期。

到目前为止,我尝试了以下几点:

代码语言:javascript
运行
复制
db.getCollection('user').aggregate([
   {$unwind: "$training"},
   {$project: {
      duration: {"$divide":[{$subtract: ['$training.to', '$education.from'] }, 1000 * 60 * 60 * 24 * 365]}
   }},
   {$group: {
     _id: '$_id',
     "duration": {$sum: '$duration'}  
   }}]
])

但该方法存在以下问题: 1-不能以期望的格式分别计算每个训练周期,不能将这些周期的总和计算为总训练周期。因为在训练期之间可能会有休息。2-无法计算正在进行的培训持续时间。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-02-18 18:55:53

添加了多个$addFields阶段,以减少和计算每个培训和总培训的日、月和年差异。

这里的假设是1个月= 30天

代码语言:javascript
运行
复制
db.data.aggregate(
    [
        {
            $addFields : {
                trainingPeriod : {
                    $map : {
                        input : "$training",
                        as : "t",
                        in : {
                            year: {$subtract: [{$year : {$ifNull : ["$$t.endDate", new Date()]}}, {$year : "$$t.startDate"}]},
                            month: {$subtract: [{$month : {$ifNull : ["$$t.endDate", new Date()]}}, {$month : "$$t.startDate"}]},
                            dayOfMonth: {$subtract: [{$dayOfMonth : {$ifNull : ["$$t.endDate", new Date()]}}, {$dayOfMonth : "$$t.startDate"}]}
                        }
                    }
                }
            }
        },
        {
            $addFields : {
                trainingPeriod : {
                    $map : {
                        input : "$trainingPeriod",
                        as : "d",
                        in : {
                            year: "$$d.year",
                            month: {$cond : [{$lt : ["$$d.dayOfMonth", 0]}, {$subtract : ["$$d.month", 1]}, "$$d.month" ]},
                            day: {$cond : [{$lt : ["$$d.dayOfMonth", 0]}, {$add : [30, "$$d.dayOfMonth"]}, "$$d.dayOfMonth" ]}
                        }
                    }
                }
            }
        },
        {
            $addFields : {
                trainingPeriod : {
                    $map : {
                        input : "$trainingPeriod",
                        as : "d",
                        in : {
                            year: {$cond : [{$lt : ["$$d.month", 0]}, {$subtract : ["$$d.year", 1]}, "$$d.year" ]},
                            month: {$cond : [{$lt : ["$$d.month", 0]}, {$add : [12, "$$d.month"]}, "$$d.month" ]},
                            day: "$$d.day"
                        }
                    }
                }
            }
        },
        {
            $addFields : {
                total : {
                    $reduce : {
                        input : "$trainingPeriod",
                        initialValue : {year : 0, month : 0, day : 0},
                        in : {
                            year: {$add : ["$$this.year", "$$value.year"]},
                            month: {$add : ["$$this.month", "$$value.month"]},
                            day: {$add : ["$$this.day", "$$value.day"]}
                        }
                    }
                }
            }
        },
        {
            $addFields : {
                total : {
                    year : "$total.year",
                    month : {$add : ["$total.month", {$floor : {$divide : ["$total.day", 30]}}]},
                    day : {$mod : ["$total.day", 30]}
                }
            }
        },
        {
            $addFields : {
                total : {
                    year : {$add : ["$total.year", {$floor : {$divide : ["$total.month", 12]}}]},
                    month : {$mod : ["$total.month", 12]},
                    day : "$total.day"
                }
            }
        }
    ]
).pretty()

结果

代码语言:javascript
运行
复制
{
    "_id" : ObjectId("5a87fcf68a2c0b7c0666140f"),
    "training" : [
        {
            "id" : ObjectId("5a01867959e2868ce09fbbc5"),
            "startDate" : ISODate("2012-12-18T00:00:00Z"),
            "endDate" : ISODate("2015-05-31T00:00:00Z"),
            "inProgress" : false
        },
        {
            "id" : ObjectId("5a01899959e2868ce09fbbc6"),
            "startDate" : ISODate("2017-11-02T00:00:00Z"),
            "endDate" : ISODate("2017-11-25T00:00:00Z"),
            "inProgress" : false
        },
        {
            "id" : ObjectId("5a01899959e2868ce09fbbc8"),
            "startDate" : ISODate("2018-01-02T00:00:00Z"),
            "endDate" : null,
            "inProgress" : true
        }
    ],
    "trainingPeriod" : [
        {
            "year" : 2,
            "month" : 5,
            "day" : 13
        },
        {
            "year" : 0,
            "month" : 0,
            "day" : 23
        },
        {
            "year" : 0,
            "month" : 1,
            "day" : 16
        }
    ],
    "total" : {
        "year" : 2,
        "month" : 7,
        "day" : 22
    }
}
> 
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48840006

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档