MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

serie temporali e framework di aggregazione (mongo)

Il tuo errore è come stai calcolando _id per $group operatore, in particolare il suo second parte:

second: { $subtract: [
    { $second: "$time" },
    { $mod: [
        { $second: "$time" },
        timeBlock / 1000
    ]}
]}

Quindi, invece di dividere tutti i tuoi dati in 10 timeBlock blocchi lunghi millisecondi a partire da new Date(end - 10 * timeBlock) , lo stai dividendo in 11 blocchi partendo dal divisore più vicino di timeBlock .

Per risolverlo dovresti prima calcolare delta = end - $time e poi usalo al posto dell'originale $time per creare il tuo _id .

Ecco un esempio di cosa intendo:

Document.aggregate({
    $match: {
        time: {
            $gte: new Date(end - 10 * timeBlock),
            $lt: new Date(end)
        }
    }
}, {
    $project: {
        time: 1,
        delta: { $subtract: [
            new Date(end),
            "$time"
        ]}
    }
}, {
    $project: {
        time: 1,
        delta: { $subtract: [
            "$delta",
            { $mod: [
                "$delta",
                timeBlock
            ]}
        ]}
    }
}, {
    $group: {
        _id: { $subtract: [
            new Date(end),
            "$delta"
        ]},
        count: { $sum: 1 }
    }
}, {
    $project: {
        time: "$_id",
        count: 1,
        _id: 0
    }
}, {
    $sort: {
        time: 1
    }
}, function(err, result) {
    // ...
})

Ti consiglio anche di utilizzare valori di tempo grezzi (in millisecondi), perché è molto più semplice e perché ti impedirà di commettere errori. Puoi trasmettere time in timeParts dopo $group usando $project operatore.