MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

série chronologique et cadre d'agrégation (mongo)

Votre erreur est la façon dont vous calculez _id pour $group opérateur, en particulier son second partie :

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

Ainsi, au lieu de diviser toutes vos données en 10 timeBlock morceaux de millisecondes à partir de new Date(end - 10 * timeBlock) , vous le divisez en 11 morceaux à partir du diviseur le plus proche de timeBlock .

Pour résoudre ce problème, vous devez d'abord calculer delta = end - $time puis utilisez-le à la place du $time d'origine pour construire votre _id .

Voici un exemple de ce que je veux dire :

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

Je vous recommande également d'utiliser des valeurs de temps brutes (en millisecondes), car c'est beaucoup plus facile et cela vous évitera de faire une erreur. Vous pouvez lancer time dans timeParts après $group en utilisant $project opérateur.