MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Mongoose - Zugriff auf verschachteltes Objekt mit .populate

Hier ist eine vereinfachte Version dessen, was Sie wollen.

Grunddaten zum Einrichten, zuerst die "Studenten":

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

Und dann die "Teams"-Sammlung:

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

So geht's:

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 ) );
    });

  });

Und es gibt Ihnen die Ergebnisse:

{
    "_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
            }
        }
    ]
}

Sie brauchen das "async"-Modul wirklich nicht, aber ich bin sozusagen nur "in der Gewohnheit". Es "blockiert" nicht, daher halte ich es für besser.

Wie Sie sehen können, initialisieren Sie .populate() call tut nichts, da er erwartet, eine _id "abzutasten". Wert in der Fremdsammlung aus einem Array-Input, was dies "genau genommen" nicht ist, da der "Schlüssel" auf "Schüler" steht, der den "Fremdschlüssel" enthält.

Ich habe das wirklich in einer aktuellen Antwort hier behandelt , vielleicht nicht genau spezifisch für Ihre Situation. Es scheint, dass Ihre Suche nicht die richtige "gleiche Antwort" (wenn auch nicht genau) ergeben hat, auf die Sie sich beziehen können.