I have a collection of ProductViews
.
ProductView
{
productId: \'5b8c0f3204a10228b00a1745,
createdAt: \'2018-09-
With some javascript
and aggregation
trick.
You need to first find the dates between the date range provided.
function getDates(startDate, stopDate) {
var dateArray = []
var currentDate = moment(startDate)
var stopDate = moment(stopDate)
while (currentDate <= stopDate) {
dateArray.push(moment(currentDate).format('YYYY-MM-DD'))
currentDate = moment(currentDate).add(1, 'days')
}
return dateArray
}
const dummyArray = getDates('2018-09-01', '2018-09-05')
dummyArray = [ "2018-09-01", "2018-09-02", "2018-09-03", "2018-09-04", "2018-09-05" ]
Now with the below aggregation you can find for the dates which are not available in the database.
db.collection.aggregate([
{ "$match": { productId } },
{ "$group": {
"_id": { "$substr": ["$createdAt", 0, 10] },
"count": { "$sum": 1 },
"time": { "$avg": "$createdAt" },
}},
{ "$sort": { "_id": 1 } },
{ "$project": { "date": "$_id", "views": "$count" }},
{ "$group": { "_id": null, "data": { "$push": "$$ROOT" }}},
{ "$project": {
"data": {
"$map": {
"input": dummyArray,
"in": {
"k": "$$this",
"v": { "$cond": [{ "$in": ["$$this", "$data.date" ] }, 1, 0 ] }
}
}
}
}},
{ "$unwind": "$data" },
{ "$group": { "_id": "$data.k", "count": { "$sum": "$data.v" }}}
])
and the output will be
[
{ date: '2018-09-01', views: 1 },
{ date: '2018-09-02', views: 3 },
{ date: '2018-09-03', views: 0 },
{ date: '2018-09-04', views: 2 },
{ date: '2018-09-05', views: 5 }
]