在MongoDb中以15分钟的时间间隔进行分组

我有这样一个“状态”集合 –

{ _id: ObjectId("545a0b63b03dbcd1238b4567"), status: 1004, comment: "Rem dolor ipsam placeat omnis non. Aspernatur nobis qui nisi similique.", created_at: ISODate("2014-11-05T11:34:59.804Z") }, { _id: ObjectId("545a0b66b03dbcd1238b4568"), status: 1001, comment: "Sint et eos vero ipsa voluptatem harum. Hic unde voluptatibus et blanditiis quod modi.", created_at: ISODate("2014-11-05T11:35:02.814Z") } .... .... 

我需要从该集合中以15分钟的时间间隔对结果进行分组。

有几种方法可以做到这一点。

首先是date聚合运算符 ,它允许您剖析文档中的“date”值。 特别是“分组”作为主要意图:

 db.collection.aggregate([ { "$group": { "_id": { "year": { "$year": "$created_at" }, "dayOfYear": { "$dayOfYear": "$created_at" }, "interval": { "$subtract": [ { "$minute": "$created_at" }, { "$mod": [{ "$minute": "$created_at"}, 15] } ] } }}, "count": { "$sum": 1 } }} ]) 

第二种方法是在从另一个date对象中减去一个date对象(或其他直接的math运算)时使用一些小窍门,那么结果就是一个表示两个对象之间的纪元时间戳毫秒的数字值。 所以只要使用纪元date,就可以得到纪元的毫秒表示。 然后使用datemath间隔:

 db.collection.aggregate([ { "$group": { "_id": { "$subtract": [ { "$subtract": [ "$current_date", new Date("1970-01-01") ] }, { "$mod": [ { "$subtract": [ "$current_date", new Date("1970-01-01") ] }, 1000 * 60 * 15 ]} ] }, "count": { "$sum": 1 } }} ]) 

所以这取决于你想要什么样的输出格式的分组间隔。 两者基本上代表相同的事物,并有足够的数据重新构build为代码中的“date”对象。

您可以在分组_id后放置“分组操作符”部分中的其他任何内容。 我只是用基本的“计数”例子来代替你自己真正想要做的事情。

我喜欢在这里的其他答案,主要是使用datemath,而不是聚合date运算符,虽然有用也可能有点模糊。

这里我唯一要添加的是,您也可以通过这种方法从聚合框架中返回Date对象,而不是“数字”时间戳作为结果。 这只是一个额外的math原理相同,使用$add

 db.collection.aggregate([ { "$group": { "_id": { "$add": [ { "$subtract": [ { "$subtract": [ "$current_date", new Date(0) ] }, { "$mod": [ { "$subtract": [ "$current_date", new Date(0) ] }, 1000 * 60 * 15 ]} ] }, new Date(0) ] }, "count": { "$sum": 1 } }} ]) 

这里用JavaScript构造的Date(0)在这里以较短的forms表示相同的“时代”date,因为从历元起0毫秒是历元。 但重点是,当使用数字标识符对另一个BSONdate对象进行“添加”时,所描述条件的反向是真实的,最终结果实际上现在是一个Date

所有的驱动程序将通过这种方法将本地Datetypes返回到他们的语言。

mongo db.version()<3.0

 db.collection.aggregate([ {$match: {created_at:{$exists:1}}}, {$group: { _id: {$add:[ {$dayOfYear: "$created_at" }, {$multiply: [{$year: "$created_at"}, 1000]} ]}, count: {$sum: 1 } }}, {$sort:{_id:-1}} ]) 

另一个有用的方法

 db.collection.aggregate([ {$group: { _id: { overallTime: { $dateToString: { format: "%Y-%m-%dT%H", date: "$created_at" } }, interval: { $trunc: { $divide: [{ $minute: "$created_at" }, 15 ]}} }, }}, ]) 

对于最小小时日间间隔更容易:

 var format = "%Y-%m-%dT%H:%M"; // 1 min var format = "%Y-%m-%dT%H"; // 1 hour var format = "%Y-%m-%d"; // 1 day db.collection.aggregate([ {$group: { _id: { $dateToString: { format: format, date: "$created_at" } }, }}, ])