sql >> Base de Datos >  >> NoSQL >> MongoDB

Volver a muestrear datos de series temporales usando Javascript y Mongodb

Es algo posible. Tenga en cuenta que Pandas es una biblioteca construida explícitamente para ese tipo de tareas, y una bestia, mientras que MongoDB está destinado a ser una base de datos. Pero hay muchas posibilidades de que lo siguiente se adapte a sus necesidades, si se ignora su probable necesidad de utilizar la interpolación:

Suponiendo que tiene los siguientes datos almacenados en una colección de MongoDB llamada devices

/* 0 */
{
    "_id" : ObjectId("543fc08ccf1e8c06c0288802"),
    "t" : ISODate("2014-10-20T14:56:44.097+02:00"),
    "a" : "192.168.0.16",
    "i" : 0,
    "o" : 32
}

/* 1 */
{
    "_id" : ObjectId("543fc08ccf1e8c06c0288803"),
    "t" : ISODate("2014-10-20T14:56:59.107+02:00"),
    "a" : "192.168.0.16",
    "i" : 14243,
    "o" : 8430
}

and so on...

que, en este caso, se muestrea alrededor de cada 15 segundos, pero también podría ser irregular. Si desea volver a muestrearlo a un límite de 5 minutos para un día determinado, debe hacer lo siguiente:

var low = ISODate("2014-10-23T00:00:00.000+02:00")
var high = ISODate("2014-10-24T00:00:00.000+02:00")
var interval = 5*60*1000;
db.devices.aggregate([
  {$match: {t:{$gte: low, $lt: high}, a:"192.168.0.16"}},
  {$group: {
     _id:{
       $subtract: ["$t", {
         $mod: [{
           $subtract: ["$t", low]
         }, interval]
       }]
     },
     total: {$sum: 1},
     incoming: {$sum: "$i"},
     outgoing: {$sum: "$o"},
    }
  },
  {
    $project: {
      total: true,
      incoming: true,
      outgoing: true,
      incoming_avg: {$divide: ["$incoming", "$total"]},
      outgoing_avg: {$divide: ["$outgoing", "$total"]},
    },
  },
  {$sort: {_id : 1}}
])

Esto resultará en algo como esto

{
    "result" : [ 
        {
            "_id" : ISODate("2014-10-23T07:25:00.000+02:00"),
            "total" : 8,
            "incoming" : 11039108,
            "outgoing" : 404983,
            "incoming_avg" : 1379888.5,
            "outgoing_avg" : 50622.875
        }, 
        {
            "_id" : ISODate("2014-10-23T07:30:00.000+02:00"),
            "total" : 19,
            "incoming" : 187241,
            "outgoing" : 239912,
            "incoming_avg" : 9854.78947368421,
            "outgoing_avg" : 12626.94736842105
        }, 
        {
            "_id" : ISODate("2014-10-23T07:35:00.000+02:00"),
            "total" : 17,
            "incoming" : 22420099,
            "outgoing" : 1018766,
            "incoming_avg" : 1318829.352941176,
            "outgoing_avg" : 59927.41176470588
        },
        ...

Si desea descartar el total entrante, simplemente deje la línea en la etapa $project. incoming_average es solo un ejemplo de cómo calcular el promedio, en caso de que sus datos almacenados sean algo así como lo que rrdtool denomina un indicador (temperatura, CPU, datos del sensor). Si solo busca la suma agregada en ese intervalo de tiempo, que es el campo de entrada y salida, entonces puede omitir toda la etapa de $proyecto. Solo está ahí para calcular el promedio del intervalo de tiempo.

Consulte la agregación de Mongo de ISODate en fragmentos de 45 minutos.