在mongodb的日期分组

Mar*_*ill 53 group-by date mongodb

我正在开展一个项目,我正在跟踪一个主题的点击次数.

我正在使用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"
}
Run Code Online (Sandbox Code Playgroud)

我想在专题点击群号:ABC按天数(15天)..我知道如何组,但我怎么能由日化集团被存储在我的数据库

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

[
  {
    "date" : "date in log",
    "click" : 9 
  },  
  {
    "date" : "date in log",
    "click" : 19
  },  
]
Run Code Online (Sandbox Code Playgroud)

我已经写代码,但它会工作只有日期是字符串(代码是在这里http://pastebin.com/2wm1n1ix)...请指导我怎么做我这组

Old*_*Pro 66

使用Mongo聚合框架的新答案

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

db.col.aggregate(
   { $group: { _id: { $dayOfYear: "$date"},
               click: { $sum: 1 } } }
   )
Run Code Online (Sandbox Code Playgroud)

这将返回如下内容:

[
    {
        "_id" : 144,
        "click" : 165
    },
    {
        "_id" : 275,
        "click" : 12
    }
]
Run Code Online (Sandbox Code Playgroud)

您需要使用$match将查询限制为您感兴趣的日期范围$project并重命名_iddate.如何将一年中的某一天转换回日期作为读者的练习.:-)

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} }
])
Run Code Online (Sandbox Code Playgroud)

这将为您提供最新的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")
    }
]
Run Code Online (Sandbox Code Playgroud)

  • @Andrew:这个和所有其他答案将点击次数加上几天,相信"主题点击次数:abc天数(15天)"意味着15个分档,每天一个,分别为15天. (2认同)

min*_*ief 33

迟到的答案,但是对于记录(对于来到此页面的任何其他人):您将需要使用'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++;}
});
Run Code Online (Sandbox Code Playgroud)

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

  • 这很好用.一个小的变体是将日期舍入到一整天并使用long来进行分组而不是字符串,这使得我的分组语句快了大约5倍. (3认同)

ans*_*man 25

在mongodb中按日期获取数据组

db.getCollection('supportIssuesChat').aggregate([
{
        $group : {
           _id :{ $dateToString: { format: "%Y-%m-%d", date: "$createdAt"} },
           list: { $push: "$$ROOT" },
           count: { $sum: 1 }
        }
}
])
Run Code Online (Sandbox Code Playgroud)


Jon*_*nga 19

这可以帮助

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);
}
Run Code Online (Sandbox Code Playgroud)


mha*_*ttu 7

这个问题已经有很多答案,但是我对任何一个都不满意。多年来,MongoDB有所改进,现在有更简单的方法可以做到这一点。乔纳斯·托曼加Jonas Tomanga)的答案是正确的,但有点太复杂了。

如果您使用的是MongoDB 3.0或更高版本,则按以下方式按日期分组。我从$match汇总开始,因为作者还询问了如何限制结果。

db.yourCollection.aggregate([
  { $match: { date: { $gte: ISODate("2019-05-01") } } },
  { $group: { _id: { $dateToString: { format: "%Y-%m-%d", date: "$date"} }, count: { $sum: 1 } } },
  { $sort: { _id: 1} }
])
Run Code Online (Sandbox Code Playgroud)


enr*_*cog 4

还没有使用 MongoDB 那么多,所以我不太确定。但是你不能使用完整的Javascript吗?
因此,您可以使用 Javascript 类解析日期Date,创建当天的日期,并将其设置为“out”属性的键。如果该键已存在,则始终添加一个,否则使用 value = 1 创建新的(第一次单击)。下面是带有改编后的reduce函数的代码(未经测试的代码!):

db.coll.group(
{
   key:{'date':true},
   initial: {retVal: {}},
   reduce: function(doc, prev){
              var date = new Date(doc.date);
              var dateKey = date.getFullYear()+''+date.getMonth()+''+date.getDate();
              (typeof prev.retVal[dateKey] != 'undefined') ? prev.retVal[dateKey] += 1 : prev.retVal[dateKey] = 1;
            }, 
   cond: {topic:"abc"}
}
)
Run Code Online (Sandbox Code Playgroud)