Skip to content

Instantly share code, notes, and snippets.

@xseignard
Created January 26, 2015 16:37
Show Gist options
  • Save xseignard/244a30ebe46d6bb59c00 to your computer and use it in GitHub Desktop.
Save xseignard/244a30ebe46d6bb59c00 to your computer and use it in GitHub Desktop.
aggregationCroustillante.js
// 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