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

Mongoose - accéder à un objet imbriqué avec .populate

Voici une version simplifiée de ce que vous voulez.

Données de base à mettre en place, d'abord les "élèves":

{ 
   "_id" : ObjectId("53aa90c83ad07196636e175f"), 
   "name" : "Bill",
   "rollNo" : 1,
   "class" : 12 
},
{ 
    "_id" : ObjectId("53aa90e93ad07196636e1761"),
    "name" : "Ted",
    "rollNo" : 2,
    "class" : 12
}

Et puis la collection "équipes" :

{ 
    "_id" : ObjectId("53aa91b63ad07196636e1762"),
    "name" : "team1",
    "lead" : "me",
    "students" : [ 
        { 
            "block" : 1,
            "status" : "Y",
            "student" : ObjectId("53aa90c83ad07196636e175f")
        },
        { 
            "block" : 2,
            "status" : "N",
            "student" : ObjectId("53aa90e93ad07196636e1761")
        }
    ]
}

Voici comment procéder :

var async = require('async'),
    mongoose = require('mongoose');
    Schema = mongoose.Schema;

mongoose.connect('mongodb://localhost/team');

var teamSchema = new Schema({
  name: String,
  lead: String,
  students: [{
    block: Number,
    status: String,
    student: {
      type: Schema.ObjectId, ref: 'Student'
    }
  }]
});

var studentSchema = new Schema({
  name: String,
  rollNo: Number,
  class: Number
});

var Team = mongoose.model( "Team", teamSchema );
var Student = mongoose.model( "Student", studentSchema );

Team.findById("53aa91b63ad07196636e1762")
  .select('students')
  .exec(function(err, team) {
    console.log( team );

    async.forEach(team.students, function(student,callback) {
      Student.populate(
        student,
        { "path": "student" },
        function(err,output) {
          if (err) throw err;
          callback();
        }
      );
    },function(err) {
      console.log( JSON.stringify( team, undefined, 4 ) );
    });

  });

Et il vous donne les résultats :

{
    "_id": "53aa91b63ad07196636e1762",
    "students": [
        {
            "block": 1,
            "status": "Y",
            "student": {
                "_id": "53aa90c83ad07196636e175f",
                "name": "Bill",
                "rollNo": 1,
                "class": 12
            }
        },
        {
            "block": 2,
            "status": "N",
            "student": {
                "_id": "53aa90e93ad07196636e1761",
                "name": "Ted",
                "rollNo": 2,
                "class": 12
            }
        }
    ]
}

Vous n'avez vraiment pas besoin du module "async", mais je suis juste "dans l'habitude" pour ainsi dire. Il ne "bloque" pas donc je le considère mieux.

Donc, comme vous pouvez le voir, vous initialisez .populate() l'appel ne fait rien car il s'attend à "clé" d'un _id valeur dans la collection étrangère à partir d'une entrée de tableau, ce qui "à proprement parler" n'est pas le cas car la "clé" est sur "l'étudiant" contenant la "clé étrangère".

J'ai vraiment couvert cela dans une réponse récente ici , peut-être pas exactement spécifique à votre situation. Il semble que votre recherche n'ait pas donné la "même réponse" correcte (mais pas exactement) pour que vous puissiez vous y référer.