Database
db={"users":[{"_id":1,"name":"John"},{"_id":2,"name":"Sally"}],"habits":[{"_id":512,"userId":1,"frequency":{"type":"daily"},"name":"sleeping","time":60000},{"_id":632,"userId":1,"frequency":{"type":"daily"},"name":"meditation",/**the day of the week corresponding to mongo's*/"days":[/**sunday*/1,/**monday*/2,/** saturday*/6],/**milliseconds past midnight*/"time":6810000},{"_id":787,"userId":2,"name":"flossing","frequency":{"type":"weekly","days":[/**tuesday*/3,/**thursday*/5]}}]}
Query
db.habits.aggregate([{"$addFields":{"instances":{$map:{input:{/**make an array with 30 items*/$range:[/**start tomorrow (days past $$NOW)*/1,/**stop 30 days out (days past $$NOW)*/31,/**just 1 per day*/1]},as:"instance",in:{/**construct the instance*/userId:"$userId",habitId:"$_id",activity:"$name",frequency:"$frequency",time:"$time",date:{$add:[{$add:[{$dateTrunc:{date:"$$NOW",unit:"day"}},{"$multiply":[/** 1 to 31, from the $range above*/"$$instance",/**24 hours in a day*/24,/**60 minutes in an hour*/60,/**60,000 ms in a minute*/60000]}]},{"$ifNull":["$time",0]}]}}}}}},{"$project":{instances:{/**only show instances that are daily or weekly and align to the days of week*/"$filter":{"input":"$instances","as":"instance","cond":{$or:[{$eq:["daily","$$instance.frequency.type"]},{$and:[{$eq:["weekly","$$instance.frequency.type"]},{$in:[{"$dayOfWeek":"$$instance.date"},{"$ifNull":["$$instance.frequency.days",[]]}]}]}]}}}}},{$unwind:"$instances"},{$replaceRoot:{newRoot:"$instances"}},{$project:{frequency:false,time:false}}])