Created
January 26, 2015 16:37
-
-
Save xseignard/244a30ebe46d6bb59c00 to your computer and use it in GitHub Desktop.
aggregationCroustillante.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // function to aggregate values of the last 24h of a given sensor, according to its strategy | |
| var last24 = function(sensorConf, callback) { | |
| // get current hour in order to make some relative calculations | |
| var current = moment(); | |
| var currentHour = current.utc().hour(); | |
| // get yesterday date (from h-23 to h+1 to get the running hour, e.g. from 2h yesterday to 2h today when it's 1h) | |
| var yesterday = current.startOf('hour').add(1, 'h').subtract(24, 'h').toDate(); | |
| var aggregate = Event.aggregate(); | |
| if (sensorConf) { | |
| // match events from date and with the given name | |
| aggregate.match({ | |
| date: { $gte : yesterday }, | |
| name: sensorConf.name | |
| }); | |
| } | |
| else { | |
| // match events from date | |
| aggregate.match({ | |
| date: { $gte : yesterday } | |
| }); | |
| } | |
| // only keep the hour part of the date, since we know all matched events happened during the last 24h | |
| aggregate.project({ | |
| name: 1, | |
| value: 1, | |
| hour : {'$hour' : '$date'} | |
| }); | |
| // get sum and avg for each name/hour tuple | |
| aggregate.group({ | |
| _id: { name: '$name', hour: '$hour' }, | |
| sum: { $sum: '$value' }, | |
| avg: { $avg: '$value' } | |
| }); | |
| // make a condition to calculate the sum or the avg according to the sensor name | |
| aggregate.project({ | |
| _id: 1, | |
| value: { | |
| $cond: [ | |
| { $or: [ | |
| { $eq: [ '$_id.name', 'watt' ] }, | |
| { $eq: [ '$_id.name', 'sound' ] }, | |
| { $eq: [ '$_id.name', 'degrees' ] }, | |
| { $eq: [ '$_id.name', 'light' ] }, | |
| { $eq: [ '$_id.name', 'fridgeDegrees' ] }, | |
| { $eq: [ '$_id.name', 'devices' ] } | |
| ]}, | |
| '$avg', | |
| '$sum' | |
| ] | |
| } | |
| }); | |
| // if it's devices, we need to return an integer average value | |
| aggregate.project({ | |
| _id: 1, | |
| value: { | |
| $cond: [ | |
| { $eq: [ '$_id.name', 'devices' ] }, | |
| { $subtract: [ '$value' , { $mod: [ '$value', 1 ] } ] }, | |
| '$value' | |
| ] | |
| } | |
| }); | |
| // re-arrange data | |
| // calculate hour ago, instead of the plain hour | |
| // first subtract the hour returned by the query to the current hour | |
| aggregate.project({ | |
| _id: '$_id.name', | |
| values: { | |
| hour: { $subtract: [ currentHour, '$_id.hour' ] }, | |
| value : '$value' | |
| } | |
| }); | |
| // then if the result of the subtraction is negative, it means it's an hour of the day ago | |
| // if so remove 24h, else leave the hour as is | |
| aggregate.project({ | |
| _id: '$_id', | |
| values: { | |
| hourAgo: { | |
| $cond: [ | |
| { $lt: [ '$values.hour', 0 ] }, | |
| { $add: ['$values.hour', 24] }, | |
| '$values.hour' | |
| ] | |
| }, | |
| value : '$values.value' | |
| } | |
| }); | |
| // sort the result by ascending values.hourAgo | |
| aggregate.sort('values.hourAgo'); | |
| // then push each values in an array | |
| aggregate.group({ | |
| _id: '$_id', | |
| values: { | |
| $push: { | |
| hourAgo: '$values.hourAgo', | |
| value: '$values.value' | |
| } | |
| } | |
| }); | |
| aggregate.exec(callback); | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment