Hello. I have timeseries data as events coming in at random times. They are not ongoing metrics, but rather events. “This device went online.” “This device went offline.”
I need to report on the number of actual transitions within a time range. Because there are occasionally same-state events, for example two “went online” events in a row, I need to “seed” the data with the state previous to the time range. If I have one event in my time range, I need to compare it to the previous in order to determine if something actually changed.
I already have aggregation stages that remove same-state events.
Is there a way to add “the latest, previous event” to the data in the pipeline without writing two queries? A $facet stage totally ruins performance.
For “previous”, I’m currently trying something like this in a separate query, but it’s very slow on the millions of records:
// Get the latest event before a given date
db.devicemetrics.aggregate([
{
$match: {
'device.someMetadata': '70b28808-da2b-4623-ad83-6cba3b20b774',
time: {
$lt: ISODate('2023-01-18T07:00:00.000Z'),
},
someValue: { $ne: null },
},
},
{ $sort: { time: -1 } },
{
$group: {
_id: '$device._id',
lastEvent: { $first: '$$ROOT' },
},
},
{
$replaceRoot: { newRoot: '$lastEvent' },
}
]);