Reputation: 57
I am trying to make a system where i have to make an average of data of 2 mins and display it to the user. I tried groupby aggregate functions. But maybe I did not write the query properly.
[
{
deviceid: 1,
bucketSize: 4,
first: 1573833152,
last: 1573833155,
samples: [
{
val: 10,
time: 1573833152
},
{
val: 15,
time: 1573833153
},
{
val: 14,
time: 1573833154
},
{
val: 16,
time: 1573833165
},
{
val: 22,
time: 1573833166
},
{
val: 26,
time: 1573833167
},
{
val: 27,
time: 1573833168
},
{
val: 28,
time: 1573833169
},
{
val: 29,
time: 1573833170
}
]
},
{
deviceid: 1,
bucketSize: 4,
first: 1573833156,
last: 1573833160,
samples: [
{
val: 30,
time: 1573833156
},
{
val: 45,
time: 1573833157
},
{
val: 54,
time: 1573833158
},
{
val: 60,
time: 1573833159
},
{
val: 70,
time: 1573833160
}
]
},
{
deviceid: 1,
bucketSize: 4,
first: 1573833161,
last: 1573833165,
samples: [
{
val: 10,
time: 1573833161
},
{
val: 15,
time: 1573833162
},
{
val: 14,
time: 1573833163
},
{
val: 20,
time: 1573833164
}
]
}
]
This is the data. I need an average of every 2 minutes. I am new to Mongo. Hence stuck with this problem. Thank you really very much in advance.
Playground for average. Which one of the stackoverflow member helped me to create. https://mongoplayground.net/p/tuTzNeO2DKx
Upvotes: 3
Views: 1027
Reputation: 59557
For me it is not fully clear what you mean by "I need an average of every 2 minutes". All your sample data fall into one 2-Minute interval.
Anyway, the key operation is to determine the 2-Minutes interval. Afterwards you can $group
by samples.interval
value. You can do it like this one:
db.collection.aggregate([
{ $unwind: "$samples" },
{
// convert time value into proper 'Date' object and split into parts
$addFields: {
"samples.interval": {
$dateToParts: {
date: {
$toDate: {
$multiply: [1000, "$samples.time"]
}
}
}
}
}
},
{
// Build new 2-Minute interval. `samples.interval` represents the start time of 2-Minute interval
$addFields: {
"samples.interval": {
$dateFromParts: {
year: "$samples.interval.year",
month: "$samples.interval.month",
day: "$samples.interval.day",
hour: "$samples.interval.hour",
minute: { $subtract: ["$samples.interval.minute", { $mod: ["$samples.interval.minute", 2] }] }
}
}
}
},
{
$group: {
_id: {
deviceid: "$deviceid",
interval: "$samples.interval"
},
average: { $avg: "$samples.val" }
}
},
{ $replaceRoot: { newRoot: { $mergeObjects: ["$$ROOT", "$_id"] } } },
{ $unset: "_id" }
])
You may use
minute: { $add: [1, { $subtract: ["$samples.interval.minute", { $mod: ["$samples.interval.minute", 2] }] }] }
in order to get the interval as interval: ISODate("2019-11-15T17:27:00.000+0100") ± 1 Minute
rather than "start of interval"
Upvotes: 2