首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用.populate访问嵌套对象

用.populate访问嵌套对象
EN

Stack Overflow用户
提问于 2014-06-25 07:34:26
回答 4查看 12.2K关注 0票数 6

图式定义

Team.js

代码语言:javascript
复制
var TeamSchema = new Schema({
    // Team Name.
    name: String,
    lead: String,
    students :type: [{
      block : Number,
      status : String,
      student : {
        type: Schema.ObjectId,
        ref: 'Student'
    }]
});

Student.js

代码语言:javascript
复制
var StudentSchema = new Schema({
   name: String,
   rollNo : Number,
   class : Number
});

如何填充“学生”以获得输出,如下所示:

团队

代码语言:javascript
复制
{
    "__v": 1,
    "_id": "5252875356f64d6d28000001",
    "students": [
        {
            "__v": 1,
            "_id": "5252875a56f64d6d28000002",
             block : 1,
             status : joined,
            "student": {
                "name": Sumeeth
                "rollNo" : 2
                "class" : 5
            }
        },
        {
            "__v": 1,
            "_id": "5252875a56f64d6d28000003",
            block : 1,
            status : joined,
            "student": {
                "name": Sabari
                "rollNo" : 3
                "class" : 4
            }
        }
    ],
    "lead": "Ratha",   
}

这是我使用Mongoose获取文档时使用的JS:

代码语言:javascript
复制
Team.findOne({
    _id: req.team._id
})            
.populate('students')
.select('students')
.exec(function(err, team) {
    console.log(team);
    var options = {
        path: 'students.student',
        model: 'Student'
    };
    Student.populate(team.students,options,function(err, students) {
        console.log(students);
        if (err) {
            console.log(students);
            res.send(500, {
                message: 'Unable to query the team!'
            });
        } else {
            res.send(200, students);
        }
    });
});

在我的控制台输出中,我得到以下内容:

代码语言:javascript
复制
{ _id: 53aa434858f760900b3f2246,
  students
   [ { block : 1
       status: 'joined'
       _id: 53aa436b58f760900b3f2249 },
     { block : 1
       status: 'joined'
       _id: 53aa436b58f760900b3f2250 }]
}

预期产出是:

代码语言:javascript
复制
  { _id: 53aa434858f760900b3f2246,
      students
       [ { block : 1
           status: 'joined'
           student :{
              "name": Sumeeth
              "rollNo" : 2
              "class" : 5
           } 
         },
         { block : 1
           status: 'joined'
           student :{
               "name": Sabari
              "rollNo" : 3
              "class" : 4
           } 
        }
     ]
    }

如果我错了,请有人帮我。我应该如何使用.populate,这样,我就可以得到整个学生对象,而不仅仅是它的id。

参考资料:Populate nested array in mongoose

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-06-25 11:23:32

以下是您所需内容的简化版本。

基本数据要建立起来,首先是“学生”:

代码语言:javascript
复制
{ 
   "_id" : ObjectId("53aa90c83ad07196636e175f"), 
   "name" : "Bill",
   "rollNo" : 1,
   "class" : 12 
},
{ 
    "_id" : ObjectId("53aa90e93ad07196636e1761"),
    "name" : "Ted",
    "rollNo" : 2,
    "class" : 12
}

然后“团队”收集:

代码语言:javascript
复制
{ 
    "_id" : ObjectId("53aa91b63ad07196636e1762"),
    "name" : "team1",
    "lead" : "me",
    "students" : [ 
        { 
            "block" : 1,
            "status" : "Y",
            "student" : ObjectId("53aa90c83ad07196636e175f")
        },
        { 
            "block" : 2,
            "status" : "N",
            "student" : ObjectId("53aa90e93ad07196636e1761")
        }
    ]
}

你就是这样做的:

代码语言:javascript
复制
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 ) );
    });

  });

它给出了结果:

代码语言:javascript
复制
{
    "_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
            }
        }
    ]
}

你真的不需要“异步”模块,但我只是“习惯”而已。它没有“阻止”,因此我认为它更好。

因此,正如您可以看到的那样,初始的.populate()调用不会做任何事情,因为它期望从数组输入中从外部集合中的_id值中“键”“键”,而这个“严格说来”并不是"key“位于包含”外键“的”学生“上。

我确实在一个recent answer here中讨论过这个问题,也许并不完全是针对您的情况。似乎您的搜索没有找到正确的“相同的答案”(虽然不是确切的答案)供您参考。

票数 3
EN

Stack Overflow用户

发布于 2017-09-19 10:13:25

我一直面临着同样的问题。我用这个代码来拯救我:

代码语言:javascript
复制
Team.findOne({_id: req.team._id})
.populate({ path: "students.student"})
.exec(function(err, team) {
       console.log(team);
});
票数 4
EN

Stack Overflow用户

发布于 2017-05-24 23:55:57

你想得太多了。让猫鼬为你做这件事。

代码语言:javascript
复制
Team.findOne({
    _id: req.team._id
})            
.populate({path:'students'})
.exec(function(err, team) {
    console.log(team);
});

这将返回学生作为文档而不仅仅是ids。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24402764

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档