为了账号安全,请及时绑定邮箱和手机立即绑定

在mongodb中按日期分组

/ 猿问

在mongodb中按日期分组

不负相思意 2019-10-28 10:28:20

我正在一个项目中,在其中跟踪某个主题的点击次数。


我正在使用mongodb,我必须按日期对点击次数进行分组(我希望对15天的数据进行分组)。


我在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"

}

我想按天数(15天)对topic:abc的点击次数进行分组。.我知道如何进行分组,但是如何按存储在数据库中的日期进行分组


我正在寻找以下格式的结果


[

  {

    "date" : "date in log",

    "click" : 9 

  },  

  {

    "date" : "date in log",

    "click" : 19

  },  

]

我已经编写了代码,但是仅当日期在字符串中时才有效(代码在这里http://pastebin.com/2wm1n1ix)...请指导我如何将其分组


查看完整描述

3 回答

?
米琪卡哇伊

使用Mongo聚合框架的新答案

在询问并回答了这个问题之后,10gen发布了具有聚合框架的Mongodb 2.2版,这是现在进行此类查询的更好方法。该查询有些挑战,因为您要按日期分组,并且存储的值是时间戳,因此您必须执行一些操作以将时间戳转换为匹配的日期。出于示例目的,我将只编写一个获得正确计数的查询。


db.col.aggregate(

   { $group: { _id: { $dayOfYear: "$date"},

               click: { $sum: 1 } } }

   )

这将返回类似:


[

    {

        "_id" : 144,

        "click" : 165

    },

    {

        "_id" : 275,

        "click" : 12

    }

]

您需要使用$match来限制查询到您感兴趣的日期范围,然后$project重命名_id为date。读者如何练习如何将一年中的日期转换回日期。:-)


10gen有一个方便的SQL到Mongo聚合转换图表,值得收藏。还有一篇有关日期聚合运算符的文章。


有点儿幻想,您可以使用:


db.col.aggregate([

  { $group: {

      _id: {

        $add: [

         { $dayOfYear: "$date"}, 

         { $multiply: 

           [400, {$year: "$date"}]

         }

      ]},   

      click: { $sum: 1 },

      first: {$min: "$date"}

    }

  },

  { $sort: {_id: -1} },

  { $limit: 15 },

  { $project: { date: "$first", click: 1, _id: 0} }

])

它将为您提供最近的15天,并在该date字段的每一天之内返回一些日期时间。例如:


[

    {

        "click" : 431,

        "date" : ISODate("2013-05-11T02:33:45.526Z")

    },

    {

        "click" : 702,

        "date" : ISODate("2013-05-08T02:11:00.503Z")

    },

            ...

    {

        "click" : 814,

        "date" : ISODate("2013-04-25T00:41:45.046Z")

    }

]


查看完整回答
反对 回复 2019-10-28
?
斯蒂芬大帝

答案较晚,但要记录下来(针对此页面上的其他用户):您将需要使用'keyf'参数而不是'key',因为您的密钥实际上将是日期的函数。事件(即从日期中提取的“日期”),而不是日期本身。这应该可以满足您的需求:


db.coll.group(

{

    keyf: function(doc) {

        var date = new Date(doc.date);

        var dateKey = (date.getMonth()+1)+"/"+date.getDate()+"/"+date.getFullYear()+'';

        return {'day':dateKey};

    },

    cond: {topic:"abc"},

    initial: {count:0},

    reduce: function(obj, prev) {prev.count++;}

});

有关更多信息,请查看有关聚合和分组的MongoDB文档页面:http : //www.mongodb.org/display/DOCS/Aggregation#Aggregation-Group


查看完整回答
反对 回复 2019-10-28
?
慕娘9325324

这可以帮助


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);

}


查看完整回答
反对 回复 2019-10-28

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信