Search code examples
mongodbsample-rate

MongoDB Aggregation Framework sample rate


I want to try MongoDB for my database solution, so I'm playing around with it. The Aggregation Framework is perfect and most of the documentation explains me very well what I have to do.

My data look like this:

{ "_id" :       ObjectId("54e5e79032d4796d1dec195e"), 
  "timestamp" : ISODate("2015-01-20T10:31:02.082Z"), 
  "value" :     4089 }

For example, if I want to aggregate my data per second, this is what I would do:

db.mycollection.aggregate(
 {
   $match : {
      timestamp: {$gte: ISODate("2015-01-21T12:00:00Z"), 
                  $lte: ISODate("2015-01-21T12:01:00Z")}   
   }
 },
 {
   $group : {
    _id : { $second: "$timestamp" },
    averageQuantity: { $avg: "$value" },
    count: { $sum: 1 }
  }
 }
);

My question is, what do I have to do to aggregate my data by a sample rate that's not predefined, like $second or $minute, but let's say by 30 seconds?

Using the code from my example, I would like to get 2 results returned.

Thanks in advance!


Solution

  • what do I have to do to aggregate my data by a sample rate that's not predefined, like $second or $minute, but let's say by 30 seconds?

    A lot of math in the aggregation pipeline. If you want to take a day's worth of time and group by 30 second intervals, for example, you'll need to take the timestamp and compute how many seconds into the day it represents, then turn that into a rounded # of 30 second intervals into the day and group on that.

    db.mycollection.aggregate([
        { "$project" : {
            "secs" : { 
                "$add" : [
                    { "$multiply" : [{ "$hour" : "$timestamp"}, 60, 60] },
                    { "$multiply" : [{ "$minute" : "$timestamp"}, 60] }
                    { "$second" : "$timestamp"}
                ]
            }
            "value" : 1
        } },
        { "$group" : {
            "_id" : {
                "$divide" : [
                    { "$subtract" : [
                        "$secs", 
                        { "$mod" : ["$secs", 30] }
                    ] },
                    30
                ]
            },
            "value" : { "$sum" : "$value" }
        } }
    ])