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

serie temporal y marco de agregación (mongo)

Tu error es cómo estás calculando _id para $group operador, específicamente su second parte:

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

Entonces, en lugar de dividir todos sus datos en 10 timeBlock fragmentos de milisegundos de largo a partir de new Date(end - 10 * timeBlock) , lo estás dividiendo en 11 partes a partir del divisor más cercano de timeBlock .

Para solucionarlo, primero debe calcular delta = end - $time y luego utilícelo en lugar del original $time para construir su _id .

Aquí hay un ejemplo de lo que quiero decir:

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) {
    // ...
})

También te recomiendo que uses valores de tiempo sin procesar (en milisegundos), porque es mucho más fácil y evitará que cometas un error. Podrías lanzar time en timeParts después de $group usando $project operador.