如何在MongoDB 3.4.1中使用两个字段来填充该范围涵盖的日期范围内的文档?
例如,我有以下文件:
{ start: ISODate('2017-04-01T12:30:00Z'), end: ISODate('2017-04-02T12:30:00Z') },
{ start: ISODate('2017-04-04T12:00:00Z'), end: ISODate('2017-04-04T12:30:00Z') },
{ start: ISODate('2017-04-04T12:30:00Z'), end: ISODate('2017-04-08T12:30:00Z') },
{ start: ISODate('2017-04-05T12:30:00Z'), end: ISODate('2017-04-06T12:30:00Z') },
{ start: ISODate('2017-04-08T12:30:00Z'), end: ISODate('2017-04-09T12:30:00Z') }
我希望将这些内容添加到以下直方图中:
[
{ '2017-04-01': 1 },
{ '2017-04-02': 1 },
{ '2017-04-04': 2 },
{ '2017-04-05': 2 },
{ '2017-04-06': 2 },
{ '2017-04-07': 1 },
{ '2017-04-08': 2 },
{ '2017-04-09': 1 }
]
如果文档的日期范围涵盖一天中的任何部分,则该文档应该计入当天的1个项目。
如果可能,我想使用单个汇聚管道执行此分段。通过使用日期格式化程序(例如:
)将它们投影到单个时间戳字段,这非常简单{ $project: { day: { $dateToString: { format: '%Y-%m-%d', date: '$start' } } } }
但似乎没有那些聚合运算符支持日期范围。
答案 0 :(得分:2)
不是很简单,但这很有效。如果您需要精确的输出格式,则需要在3.4.4中引入新的$objectToArray表达式。
编辑:这不考虑闰年,因为它假定每年有365天。
const millisPerDay = 1000 * 60 * 60 * 24;
var results = db.dates.aggregate([
{
$project: {
start: 1,
range: {
$range: [
0,
{
$add: [
1,
{
$add: [
{$multiply: [365, {$subtract: [{$year: "$end"}, {$year: "$start"}]}]},
{$subtract: [{$dayOfYear: "$end"}, {$dayOfYear: "$start"}]}
]
}
]
}
]
}
}
},
{
$project: {
daysOfEvent: {
$map: {
input: "$range",
in : {$add: ["$start", {$multiply: ["$$this", millisPerDay]}]}
}
}
}
},
{$unwind: "$daysOfEvent"},
{$group: {_id: {$dateToString: {format: '%Y-%m-%d', date: "$daysOfEvent"}}, count: {$sum: 1}}},
{$sort: {_id: -1}},
{$replaceRoot: {newRoot: {$arrayToObject: [[{k: "$_id", v: "$count"}]]}}}
]);