MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

série temporal e estrutura de agregação (mongo)


Seu erro é como você está calculando _id para $group operador, especificamente seu second papel:
second: { $subtract: [
    { $second: "$time" },
    { $mod: [
        { $second: "$time" },
        timeBlock / 1000
    ]}
]}

Então, em vez de dividir todos os seus dados em 10 timeBlock fragmentos de milissegundos começando em new Date(end - 10 * timeBlock) , você está dividindo-o em 11 partes a partir do divisor mais próximo de timeBlock .

Para corrigi-lo, você deve primeiro calcular delta = end - $time e, em seguida, use-o em vez do $time original para construir seu _id .

Aqui está um exemplo do que quero dizer:
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) {
    // ...
})

Também recomendo que você use valores brutos de tempo (em milissegundos), porque é muito mais fácil e porque evitará que você cometa erros. Você pode transmitir time em timeParts depois de $group usando $project operador.