sql >> Databasteknik >  >> NoSQL >> MongoDB

Mongoose - åtkomst till kapslade objekt med .populate

Här är en förenklad version av vad du vill ha.

Grundläggande data att ställa in, först "studenterna":

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

Och sedan samlingen "lag":

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

Så här gör du:

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

  });

Och det ger dig resultaten:

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

Du behöver verkligen inte "async"-modulen, men jag är bara "i vana" så att säga. Det "blockerar" inte så därför anser jag att det är bättre.

Så som du kan se börjar du .populate() anropet gör ingenting eftersom det förväntar sig att "nyckel" av ett _id värde i den främmande samlingen från en array-ingång som detta "strängt taget" inte är så eftersom "nyckeln" är på "student" som innehåller "främmande nyckel".

Jag tog verkligen upp detta i ett nyligen svar här , kanske inte exakt för din situation. Det verkar som om din sökning inte gav rätt "samma svar" (men inte exakt) för dig att hämta referens från.



  1. använder Async i en transaktion i Spring-applikationen

  2. Hur kan jag hitta liknande dokument i MongoDB?

  3. MongoDB - Hur man hittar distinkta värden baserat på delsträng

  4. Projektion i Where-klausul Fråga av ett inbäddat dokument i MongoDB Collection med C#