我的目标是确认符合MongoDB Atlas 4.0.6中存储的必需活动日历。此计算必须在MongoDB Aggregation Framework内进行。
类似的帖子介绍了使用Ruby,JS和SQL的方法,但是我发现没有一种方法可以直接解决聚合框架。
MongoDB集合 requiredActivities 指定了事件的预期发生频率(例如,每“ 4周”进行“老教师观察”)。频率可能以天或周为单位。
{
"_id" : ObjectId("5c9ee1e03735761f24721b0b"),
"title" : "Veteran Teacher Observation",
"durationUnit" : "weeks",
"durationCount" : 4
},
{
"_id" : ObjectId("5c9ee1e03735761f24721b0b"),
"title" : "New Teacher Observation",
"durationUnit" : "days",
"durationCount" : 5
}
另一个收藏集假期标识假日。
[
{
"_id" : ObjectId("5ca807eaf1764b1f507350f0"),
"date" : ISODate("2018-12-20T00:00:00.000-08:00"),
"description" : "Winter Break",
"isHoliday" : true
},
{
"_id" : ObjectId("5ca8089df1764b1f507350f2"),
"date" : ISODate("2018-12-21T16:00:00.000-08:00"),
"description" : "Winter Break",
"isHoliday" : true
},
{
"_id" : ObjectId("5ca808acf1764b1f507350f4"),
"date" : ISODate("2018-12-24T16:00:00.000-08:00"),
"description" : "Winter Break",
"isHoliday" : true
},
{
"_id" : ObjectId("5ca808f0f1764b1f507350f7"),
"date" : ISODate("2018-12-25T16:00:00.000-08:00"),
"description" : "Winter Break",
"isHoliday" : true
},
{
"_id" : ObjectId("5ca8090bf1764b1f507350f8"),
"date" : ISODate("2018-12-31T16:00:00.000-08:00"),
"description" : "Winter Break",
"isHoliday" : true
},
{
"_id" : ObjectId("5ca8091af1764b1f507350f9"),
"date" : ISODate("2019-01-01T16:00:00.000-08:00"),
"description" : "Winter Break",
"isHoliday" : true
}
]
鉴于endDate
,所需结果是一个文件,该文件标识了针对周末和节假日更正的合规期限。结果中必须显示排除的周末和节假日。
给定endDate
为01/02/2019的所需结果是:
{
"_id" : ObjectId("5c9ee1e03735761f24721b0b"),
"title" : "Veteran Teacher Observation",
"durationUnit" : "weeks",
"durationCount" : 4,
"dateRangeIncludingWeekendsAndHolidays" : {
"start" : ISODate("2018-12-05T00:00:00.000-08:00"),
"end" : ISODate("2019-01-02T00:00:00.000-08:00")
},
"holidays" : [
ISODate("2018-12-20T00:00:00.000-08:00"),
ISODate("2018-12-21T00:00:00.000-08:00"),
ISODate("2018-12-24T00:00:00.000-08:00"),
ISODate("2018-12-25T00:00:00.000-08:00"),
ISODate("2018-12-31T00:00:00.000-08:00"),
ISODate("2018-01-01T00:00:00.000-08:00")
],
"weekendDays" : [
ISODate("2018-12-01T00:00:00.000-08:00"),
ISODate("2018-12-02T00:00:00.000-08:00"),
ISODate("2018-12-08T00:00:00.000-08:00"),
ISODate("2018-12-09T00:00:00.000-08:00"),
ISODate("2018-12-15T00:00:00.000-08:00"),
ISODate("2018-12-16T00:00:00.000-08:00"),
ISODate("2018-12-22T00:00:00.000-08:00"),
ISODate("2018-12-23T00:00:00.000-08:00"),
ISODate("2018-12-29T00:00:00.000-08:00"),
ISODate("2018-12-30T00:00:00.000-08:00")
],
"dateRangeExcludingWeekendsAndHolidays" : {
"start" : ISODate("2018-11-21T00:00:00.000-08:00"),
"end" : ISODate("2019-01-02T00:00:00.000-08:00")
}
}
以下查询是部分解决方案。它无需周末或假日即可处理计算。 可以修改此查询以说明周末和节假日吗?是否有更好的方法?
const endDate = new ISODate("2019-01-02T00:00:00.000-08:00");
endDate.setHours(0, 0, 0, 0);
const ms1d = 24 * 60 * 60 * 1000; /* milliseconds per day */
const ms1w = 7 * ms1d; /* milliseconds per week */
db.requiredActivities.aggregate([
{
$addFields: {
dateRange: {
$cond: {
if: { $eq: ["$durationUnit", "weeks"] },
then: {
start: {
$subtract: [endDate, { $multiply: [ms1w, "$durationCount"] }]
},
end: endDate
},
else: {
start: {
$subtract: [endDate, { $multiply: [ms1d, "$durationCount"] }]
},
end: endDate
}
}
}
}
}
]);