group by dates in mongodb

2019-01-02 17:49发布

I am working on a project in which I am tracking number of clicks on a topic.

I am using mongodb and I have to group number of click by date( i want to group data for 15 days).

I am having data store in following format in mongodb

{ 
   "_id" : ObjectId("4d663451d1e7242c4b68e000"), 
  "date" : "Mon Dec 27 2010 18:51:22 GMT+0000 (UTC)", 
  "topic" : "abc", 
  "time" : "18:51:22"
}
{ 
    "_id" : ObjectId("4d6634514cb5cb2c4b69e000"), 
    "date" : "Mon Dec 27 2010 18:51:23 GMT+0000 (UTC)", 
    "topic" : "bce", 
    "time" : "18:51:23"
}

i want to group number of clicks on topic:abc by days(for 15 days)..i know how to group that but how can I group by date which are stored in my database

I am looking for result in following format

[
  {
    "date" : "date in log",
    "click" : 9 
  },  
  {
    "date" : "date in log",
    "click" : 19
  },  
]

I have written code but it will work only if date are in string (code is here http://pastebin.com/2wm1n1ix) ...please guide me how do I group it

8条回答
时光乱了年华
2楼-- · 2019-01-02 18:32

This can help

return new Promise(function(resolve, reject) {
db.doc.aggregate(
            [
                { $match: {} },
                { $group: { _id: { $dateToString: { format: "%Y-%m-%d", date: "$date" } }, count: { $sum: 1 } } },
                { $sort: { _id: 1 } }
            ]
        ).then(doc => {
            /* if you need a date object */
            doc.forEach(function(value, index) {
                  doc[index]._id = new Date(value._id);
              }, this);
            resolve(doc);
        }).catch(reject);
}
查看更多
孤独总比滥情好
3楼-- · 2019-01-02 18:34

Of course, that is a good solution. Aside from that you can group dates by days as strings (as that answer propose) or you can get the beginning of dates by projecting date field (in aggregation) like that:

{'$project': {
    'start_of_day': {'$subtract': [
        '$date',
        {'$add': [
            {'$multiply': [{'$hour': '$date'}, 3600000]},
            {'$multiply': [{'$minute': '$date'}, 60000]},
            {'$multiply': [{'$second': '$date'}, 1000]},
            {'$millisecond': '$date'}
        ]}
    ]},
}}

It gives you this:

{
    "start_of_day" : ISODate("2015-12-03T00:00:00.000Z")
},
{
    "start_of_day" : ISODate("2015-12-04T00:00:00.000Z")
}

It has some pluses: you can manipulate with your days in date type (not number or string), it allows you to use all of the date aggregation operators in following aggregation operations and gives you date type on the output.

查看更多
登录 后发表回答