1
votes

Comment agréger un tableau de paires ObjectId avec leur collection appropriée

J'ai une collection de cours dans laquelle j'attribue des enseignants pour chaque matière de ce cours. L'attribution est enregistrée en tant que tableau de JSON, veuillez consulter le document de référence ci-dessous.

{
   "_id" : ObjectId("5cc7d72d8e165005cbef939e"),
   "isAssigned" : true,
   "name" : "11",
   "section" : "A",
   "allotment" : [
       {
           "subject" : {
             _id: ObjectId("5cc3f7cc88e95a0c8e8ccd7d"),
             name: "English",
             code: "EN"
           }
           "teacher" : {
              _id: ObjectId("5cbee0e37a3c852868ec9797"),
              name: "Alister"
           }
       },
       {
           "subject" : {
             _id: ObjectId("5cc3f80e88e95a0c8e8ccd7e"),
             name: "Science",
             code: "SC"
           }
           "teacher" : {
              _id: ObjectId("5cbee10c7a3c852868ec9798"),
              name: "Frank"
           }
       }
   ]
}

J'essaie de faire correspondre les champs sujet et enseignant avec leur doc de deux collections différentes. Je pourrais les obtenir dans deux tableaux différents, mais je ne pouvais pas les obtenir comme structuré dans ma sortie attendue

Doc dans la collection des enseignants

{
 isAssigned: true
 name: "11"
 section: "A"
 subjectInfo:[
  {_id: "5cc3f7cc88e95a0c8e8ccd7d", name:"English", code:"EN"}
  {_id: "5cc3f80e88e95a0c8e8ccd7e", name: "Science", code:"SC"}
 ]
 teacherInfo:[
  {_id: ObjectId("5cbee0e37a3c852868ec9797"),name: "Alister"},
  { _id: ObjectId("5cbee10c7a3c852868ec9798"),name: "Frank"}
 ]
}

Doc dans le sujet

Course.aggregate([
               {"$match": matchQuery},
               {"$lookup": {
                   "from": "subjects",
                   "localField": "allotment.subject",
                   "foreignField": "_id",
                   "as": "subjectInfo"
                   }
               },
               {"$lookup": {
                   "from": "teachers",
                   "localField": "allotment.teacher",
                   "foreignField": "_id",
                   "as": "teacherInfo"}
               },
               ])

Requête que j'ai essayée

{
 _id: ObjectId("5cc3f7cc88e95a0c8e8ccd7d"),
 name: "English",
 code: "EN"
}

Résultat de cette requête

{
 _id: ObjectId("5cbee0e37a3c852868ec9797"),
 name: "Alister"
}

Sortie expansée

{
   "_id" : ObjectId("5cc7d72d8e165005cbef939e"),
   "isAssigned" : true,
   "name" : "11",
   "section" : "A",
   "allotment" : [
       {
           "subject" : ObjectId("5cc3f7cc88e95a0c8e8ccd7d"),
           "teacher" : ObjectId("5cbee0e37a3c852868ec9797")
       },
       {
           "subject" : ObjectId("5cc3f80e88e95a0c8e8ccd7e"),
           "teacher" : ObjectId("5cbee10c7a3c852868ec9798")
       }
   ]
}


1 commentaires

Utilisez les options de remplissage de mangouste, ce lien peut être utile pour vous stackoverflow .com / questions / 19222520 /…


3 Réponses :



2
votes

Déroulez simplement le tableau avant les recherches:

{ $group : { 
         _id: "$_id",
         name: {$first: "$name"},
         section: {$first: "$section},
         isAssigned: {$first: "$isAssigned},
         allotment: {$push: {teacher: "$teacherInfo.0", subject: "$subjectInfo.0"}}

si vous souhaitez re-grouper après cela pour restaurer le format attendu, vous pouvez ajouter:

Course.aggregate([
               {"$match": matchQuery},
               {"$unwind: "$allotment"}
               {"$lookup": {
                   "from": "subjects",
                   "localField": "allotment.subject",
                   "foreignField": "_id",
                   "as": "subjectInfo"
                   }
               },
               {"$lookup": {
                   "from": "teachers",
                   "localField": "allotment.teacher",
                   "foreignField": "_id",
                   "as": "teacherInfo"}
               },
               ])


0 commentaires

0
votes

Tout d'abord, vous devez $ dérouler le tableau allotment , puis appliquer $ lookup pour sujet , puis répéter idem pour professeurs et enfin appliquer $ group pour le combiner à l'intérieur du tableau. Voir ci-dessous la requête agrégée qui a été essayée et qui fonctionne pour moi.

    Course.aggregate([
        {"$match": matchQuery},
        {
        $unwind: '$allotment'  
        },
        {
            $lookup:{
            "from": "subjects",
            "localField": "allotment.subject",
            "foreignField": "_id",
            "as": "allotment.subject"
            }
        },
        {
        $unwind: '$allotment.subject'  
        },
        {
            "$lookup": {
            "from": "teachers",
            "localField": "allotment.teacher",
            "foreignField": "_id",
            "as": "allotment.teacher"
            }
        },
        {
        $unwind: '$allotment.teacher'  
        },
        { 
                "$group" : {
                    "_id" : "$_id", 
                    "isAssigned" : {
                        "$first" : "$isAssigned"
                    }, 
                    "name" : {
                        "$first" : "$name"
                    }, 
                    "section" : {
                        "$first" : "$section"
                    }, 
                    "allotment" : {
                        "$addToSet" : "$allotment"
                    }
                }
            }
    ])


0 commentaires