Tengo una colección en MongoDB y me gustaría obtener el promedio del value en intervalos de 24 horas para un día determinado.
Aquí está mi colección:
[ { "_id": 1, "value": 50, "created_at": 1614217700 }, { "_id": 2, "value": 60, "created_at": 1614219300 }, { "_id": 3, "value": 100, "created_at": 1614226200 }, { "_id": 4, "value": 80, "created_at": 1614227400 } ]Los documentos 3 y 4 están en el mismo intervalo de horas, por lo que el promedio de 80 y 100 es 90. Este es un ejemplo de lo que espero como resultado (o algo similar).
[ { "time": 0, "avg_value": null }, { "time": 1, "avg_value": 50 }, { "time": 2, "avg_value": 60 }, { "time": 3, "avg_value": null }, { "time": 4, "avg_value": 90 }, , , , { "time": 23, "avg_value": null } ]Aquí puedes encontrar mi ejemplo: https://mongoplayground.net/p/YaAeebapbD-
Cualquier idea será muy apreciada. ¡Gracias!
Es posible para las horas disponibles en la base de datos, para valores nulos necesita preparar una matriz estática y fusionarla con el resultado,
$multiply created_at con 1000 para convertirlo a milisegundos$toDate para convertir milisegundos a fecha ISO$hour para obtener la hora de la fecha ISO$group por hora que está por encima del value convertido y promedio usando $avg let result = db.collection.aggregate([ { "$match": { "created_at": { "$gte": 1614211200, "$lt": 1614297599 } } }, { $group: { _id: { $hour: { $toDate: { $multiply: ["$created_at", 1000] } } }, avg_value: { $avg: "$value" } } } ])El resultado será,
[ { "_id": 1, "avg_value": 50 }, { "_id": 2, "avg_value": 60 }, { "_id": 4, "avg_value": 90 } ]Combine las horas vacías y dé como resultado el lado del cliente. Si está utilizando Javascript/NodeJs, puede ver un ejemplo.
// RESULT FROM QUERY let result = [ { "_id": 1, "avg_value": 50 }, { "_id": 2, "avg_value": 60 }, { "_id": 4, "avg_value": 90 } ]; // GENERATE NULL HOURS FOR 23 HOURS IN ARRAY let hours = []; for (let i = 0; i<24; i++) hours.push({ _id: i, avg_value: null }); // MERGE WITH QUERY RESULT let mergeArray = hours.map(h => { let f = result.find(r => h._id === r._id); return f ? f : h; }); console.log(mergeArray);