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

Comment normaliser/réduire les données temporelles dans mongoDB ?

Voici comment vous pourriez le faire dans le cadre d'agrégation. J'utilise une petite simplification - je ne groupe que sur l'année, le mois et la date - dans votre cas, vous devrez ajouter l'heure et la minute pour les calculs plus fins. Vous avez également le choix de faire une moyenne pondérée si la distribution des points n'est pas uniforme dans l'échantillon de données que vous obtenez.

project={"$project" : {
        "year" : {
            "$year" : "$DateTime"
        },
        "month" : {
            "$month" : "$DateTime"
        },
        "day" : {
            "$dayOfWeek" : "$DateTime"
        },
        "array_serial" : 1,
        "Port Name" : 1,
        "metric" : 1
    }
};
group={"$group" : {
        "_id" : {
            "a" : "$array_serial",
            "P" : "$Port Name",
            "y" : "$year",
            "m" : "$month",
                    "d" : "$day"
        },
        "avgMetric" : {
            "$avg" : "$metric"
        }
    }
};

db.metrics.aggregate([project, group]).result

J'ai exécuté ceci avec des exemples de données aléatoires et j'ai obtenu quelque chose de ce format :

[
    {
        "_id" : {
            "a" : "12345",
            "P" : "CL1-B",
            "y" : 2012,
            "m" : 9,
            "d" : 6
        },
        "avgMetric" : 100.8
    },
    {
        "_id" : {
            "a" : "12345",
            "P" : "CL1-B",
            "y" : 2012,
            "m" : 9,
            "d" : 7
        },
        "avgMetric" : 98
    },
    {
        "_id" : {
            "a" : "12345",
            "P" : "CL1-A",
            "y" : 2012,
            "m" : 9,
            "d" : 6
        },
        "avgMetric" : 105
    }
]

Comme vous pouvez le voir, il s'agit d'un résultat par array_serial, nom de port, combinaison année/mois/date. Vous pouvez utiliser $sort pour les placer dans l'ordre dans lequel vous souhaitez les traiter à partir de là.

Voici comment étendre l'étape du projet pour inclure l'heure et la minute tout en arrondissant les minutes à la moyenne toutes les cinq minutes :

{
    "$project" : {
        "year" : {
            "$year" : "$DateTime"
        },
        "month" : {
            "$month" : "$DateTime"
        },
        "day" : {
            "$dayOfWeek" : "$DateTime"
        },
        "hour" : {
            "$hour" : "$DateTime"
        },
        "fmin" : {
            "$subtract" : [
                {
                    "$minute" : "$DateTime"
                },
                {
                    "$mod" : [
                        {
                            "$minute" : "$DateTime"
                        },
                        5
                    ]
                }
            ]
        },
        "array_serial" : 1,
        "Port Name" : 1,
        "metric" : 1
    }
}

J'espère que vous pourrez étendre cela à vos données et exigences spécifiques.