It seems that is related to the number of days between the 2 dates rather than the month/year crossing.
Here is a slightly modified algorithm based on the same principals as the one posted. The difference is that rather than having a range based on the millisecs between the 2 dates, it creates a range of the number of days between the 2 dates.
startDate: new ISODate("2014-06-01")
endDate:new ISODate("2014-07-22")
one_day = 24 * 60 * 60 * 1000
set_start_end = { "$set" : { startDate , endDate } }
// for readability and to ease of debugging, the range will be created in its own stage
set_range = { "$set" : { range: { '$range':
[ 0 ,
{ '$divide': [ { '$subtract': [ '$endDate', '$startDate' ] }, one_day ] }
]
}
// the stage that uses the range to produce the dates
set_dates = { '$set': { "dates" : { '$map': {
input: '$range',
in: {
'$add': [ '$start_date', { '$multiply' : [ '$$this', one_day ] } ]
}
} } } }
pipeline = [ set_start_end , set_range , set_dates ]
However, I stand by comment in the original post:
What you are trying to do is probably easier to do in your application code rather that try to do it on the server. Also doing this on the server will increase the data transferred from the server to the application.
Extra work done by the server is harder to scale compared to do it at the application level. For example, 2 users asks for year worth of data forces the server to generate the 2 ranges. If you just asked the data that is present, rather than generating 0 counts, then 2 ranges are generated by 2 different instances of the application. Auto-scaled.
And by reading
I really wonder why you want the database server to generated dates with 0 count if you are going to compare the 2 calandar anyway?