Fill missing dates in records

后端 未结 4 1568
佛祖请我去吃肉
佛祖请我去吃肉 2020-11-30 07:03

I have a collection of ProductViews.

ProductView

{
    productId: \'5b8c0f3204a10228b00a1745,
    createdAt: \'2018-09-         


        
4条回答
  •  执念已碎
    2020-11-30 07:54

    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 }
    ]
    

提交回复
热议问题