sql >> Databasteknik >  >> NoSQL >> MongoDB

Sampla om tidsseriedata med Javascript och Mongodb

Det är typ möjligt. Tänk på att Pandas är ett bibliotek byggt uttryckligen för den typen av uppgifter, och ett odjur på det, medan MongoDB är tänkt att vara en databas. Men chansen är stor att följande kommer att passa dina behov, om man bortser från ditt troliga behov av att använda interpolation:

Förutsatt att du har följande data lagrade i en MongoDB-samling som heter 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...

som, i det här fallet, provtas ungefär var 15:e sekund, men det kan lika gärna vara oregelbundet. Om du vill omsampla det till en gräns på 5 minuter för en viss dag, bör du göra följande:

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}}
])

Detta kommer att resultera i något liknande detta

{
    "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
        },
        ...

Om du vill kassera det totala inkommande, lämna bara raden ute i $projektstadiet. Inkommande_genomsnittet är bara ett exempel på hur man beräknar medelvärdet, om dina lagrade data är något i stil med vad rrdtool benämner en mätare (temperatur, cpu, sensordata). Om du bara är ute efter summan som aggregerats i det tidsintervallet, det vill säga det inkommande och utgående fältet, kan du lämna hela $projektstadiet utanför. Det är bara där för att beräkna medelvärdet av tidsintervallet.

Se mongosammanställning av ISODate till 45 minuters bitar




  1. pymongo - dnspython-modulen måste installeras för att använda mongodb+srv:// URIs

  2. Installerar MongoDB med Homebrew

  3. Kan inte ansluta till alternativ Mongo DB i Meteor-appen

  4. MongoDB Hitta Exact Array Match men ordningen spelar ingen roll