MongoDB使用_id按日期汇总

时间:2019-11-23 18:54:25

标签: mongodb

我要做的事情应该相对简单。我的文档称为“点击”,看起来像这样:

{
     "_id":"5dcc53f30666eacfdb9d9f59"
,     "productID":"5dcc4c47a0d861ec6a0b432b"
,     "userIP":"XX.XX.XX"
}

我只想使用_id和(假设)GetTimestamp()来计算出每天的点击次数:

[
{
     "date":"2019-11-01"
,    "clicks":"125"
}
,{
     "date":"2019-11-02"
,    "clicks":"153"
}]

我认为我可以做这样的事情,但是它不起作用:

db.clicks.aggregate([
    {"$group" : {_id: ObjectId(_id).getTimeStamp(), count:{$sum:1}}}
])

我看到的所有示例(例如:group by dates in mongodb )在文档中都有一个包含date元素的元素-我该如何使用_id来做到这一点?

2 个答案:

答案 0 :(得分:1)

我必须走,但这是一个解决您问题的出发点。可以进行优化。

[
  {
    $addFields: /** * newField - The new field name. * expression - The new field expression. */ {
      date: { $toDate: '$_id' }
    }
  },
  {
    $addFields: /** * newField - The new field name. * expression - The new field expression. */ {
      year: { $year: '$date' },
      month: { $month: '$date' },
      day: { $dayOfMonth: '$date' }
    }
  },
  {
    $addFields: /** * newField - The new field name. * expression - The new field expression. */ {
      yearString: { $toString: '$year' },
      monthString: { $toString: '$month' },
      dayString: { $toString: '$day' }
    }
  },
  {
    $addFields: /** * newField - The new field name. * expression - The new field expression. */ {
      monthYear: { $concat: ['$yearString', '-', '$monthString'] }
    }
  },
  {
    $addFields: /** * newField - The new field name. * expression - The new field expression. */ {
      fullDate: { $concat: ['$monthYear', '-', '$dayString'] }
    }
  },
  {
    $group: /** * _id - The id of the group. * field1 - The first field name. */ {
      _id: '$fullDate',
      ids: { $push: '$_id' }
    }
  },
  {
    $project: /** * specifications - The fields to *   include or exclude. */ {
      totalClicks: { $size: '$ids' }
    }
  }
];

答案 1 :(得分:0)

我将为基督徒的答案表示赞赏,但是对于任何碰到这个问题的人来说,这是一个更干净的版本:

db.clicks.aggregate(
  [

  {
    $group:  {
      _id: { $substrCP: [ {$toDate: '$_id' }, 0, 10 ] 
        },
      ids: { $push: '$_id' }
    }
  },
  {
    $project:  {
      totalClicks: { $size: '$ids' }
    }
  },
  {$sort: {_id: 1} }
]  )

主要区别在于,我只使用$ toDate而不是使用$ addFields来构建日期字符串,而是使用了一个给我YYYY-MM-DD的子字符串-之所以起作用,是因为$ toDate恰好返回了格式接近我想要的,如果您想在2019年5月13日,那么您将不得不进行大多数转换。

由于时间存储在UTC中,因此这是将其转换回本地时区的一种方法-硬编码为太平洋(8),不考虑夏令时,但至少应该给您一个思路如何弄乱它。

db.clicks.aggregate(
  [

  {
    $group:  {
      _id: { $substrCP: [ {$subtract: [{$toDate: '$_id' }, 1000*60*60*8]}, 0, 10 ] 
        },
      ids: { $push: '$_id' }
    }
  },
  {
    $project:  {
      totalClicks: { $size: '$ids' }
    }
  },
  {$sort: {_id: 1} }
]  )