每个子文档上的MongoDB日期差异,以及最终结果中它们的总和
“我的用户”集合有一个数组字段,其中包含子文档,如下面所示:每个子文档上的MongoDB日期差异,以及最终结果中它们的总和,mongodb,mongoose,aggregation-framework,Mongodb,Mongoose,Aggregation Framework,“我的用户”集合有一个数组字段,其中包含子文档,如下面所示: "training" : [ { "id" : ObjectId("5a01867959e2868ce09fbbc5"), "startDate" : ISODate("2012-12-18T00:00:00.000Z"), "endDate" : ISODate("2015-05-31T00:00:00.000Z"), "inProgress" : false }, { "id
"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-以年、月、日为单位获取每个用户的总培训周期(假设第一次培训的git差,{year:2,month:6,day:12}
,第二次培训的git差,{year:0,month:0,day:23}
,最后一次培训是持续培训,然后从当前日期开始在subtract中使用,应该是{year:0,month:1,day:15}
)
2-然后我应该计算每个培训周期的总和作为总培训周期
到目前为止,我所尝试的:
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-无法计算正在进行的培训持续时间。添加了多个
$addFields
阶段,以减少和计算每次培训和总培训的天数、月份和年份差异
这里的假设是1个月=30天
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()
结果
{
"_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
}
}
>