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

requête mongoDB pour récupérer à partir d'une collection de tableaux imbriqués

Vous aurez besoin de $elemMatch et aggregate .

db.users.aggregate([
    {
        $unwind: "$Sessions"
    },
    {
        $match: {
            "Sessions.Last_Login": {
                $gte: ISODate("2016-06-16T00:00:00.0Z"),
                $lt: ISODate("2016-06-17T00:00:00.0Z")
            }
        }
    },
    {
        $group: {
            _id: {
                _id: "$_id",
                First_Name: "$First_Name",
                Last_Name: "$Last_Name"
            },
            Sessions: {
                $push: "$Sessions"
            }
        }
    },
    {
        $project: {
            _id: "$_id._id",
            First_Name: "$_id.First_Name",
            Last_Name: "$_id.Last_Name",
            Sessions: "$Sessions"
        }
    }
])

La requête effectuera donc ces étapes :

  1. $unwind toutes les Sessions éléments
  2. $match documents dans la plage de dates
  3. $group regrouper les documents par _id , First_Name , Last_Name
  4. $project documents pour qu'ils ressemblent au format d'origine

J'ai omis certains champs, mais vous pouvez facilement l'ajouter dans $group et $project pas. Et bien sûr, vous devrez modifier la plage de dates.

Je suis préoccupé par les performances de cette requête dans une grande collection. Peut-être est-il préférable d'utiliser la première requête que j'ai donnée et de filtrer les sessions souhaitées dans votre code.

Modifier :

Comme @chridam l'a dit, cette requête ne fonctionnera que si vous modifiez Last_Login à ISODate() , ce qui est recommandé.

Modification 2 :

Mise à jour de la requête pour utiliser aggregate et correspond à la demande de récupérer uniquement Sessions à l'intérieur de la plage de dates.

Ceci est l'ancienne version :

db.users.filter({
    'Sessions': {
        '$elemMatch': {
            'Last_Login': {
                '$gte': ISODate("2016-06-16T00:00:00.0Z"),
                '$lt': ISODate("2016-06-17T00:00:00.0Z")
            }
        }
    }
})