Populate() ref 嵌套在对象数组中

Posted

技术标签:

【中文标题】Populate() ref 嵌套在对象数组中【英文标题】:Populate() ref nested in object array 【发布时间】:2014-08-13 01:30:21 【问题描述】:

我正在尝试使用 Show 模型中的数据填充()我的 User 模型中的所有订阅。我试过 .populate('subscriptions.show') 但它对结果没有任何影响。

如果我像这样将订阅设为一个普通的 Ref 数组

subscriptions: [type: Schema.Types.ObjectId, ref: 'Show']

执行填充('subscriptions')按预期工作

我查看了在 *** 上可以找到的所有类似问题以及在文档中可以找到的内容。我看不出我做错了什么。

我正在使用的完整测试文件源 https://gist.github.com/anonymous/b7b6d6752aabdd1f9b59

架构和模型

var userSchema = new Schema(
  email: String,
  displayName: String,
  subscriptions: [
    show: type: Schema.Types.ObjectId, ref: 'Show',
    favorite: type: Boolean, default: false
  ]
);

var showSchema = new Schema(
  title: String,
  overview: String,
  subscribers: [type: Schema.Types.ObjectId, ref: 'User'],
  episodes: [
    title: String,
    firstAired: Date
  ]
);

var User = mongoose.model('User', userSchema);
var Show = mongoose.model('Show', showSchema);

初始数据

var user = new User(
  email: "test@test.com",
  displayName: "bill"
);

user.save(function(err, user) 
  var show = new Show(
    title: "Some Show",
    overview: "A show about some stuff."
  );

  show.save();
  user.subscriptions.push(show);
  user.save();
);

查询

User.findOne(
  displayName: 'bill'
)
  .populate('subscriptions.show')
  .exec(function(err, user) 
    if (err) 
      console.log(err);
    

    console.log(user);
  );

结果:


  _id: 53a7a39d878a965c4de0b7f2,
  email: 'test@test.com',
  displayName: 'bill',
  __v: 1,
  subscriptions: [
    _id: 53a7a39d878a965c4de0b7f3,
    favorite: false
  ]

【问题讨论】:

那篇文章无法帮助我。也许我错过了你在那里看到的我的问题的答案。你能指出相关的部分吗? 检查这些链接 - 1.***.com/questions/24245569/… 2.***.com/questions/24185367/… 这些链接都没有帮助。与我正在做的最接近的是:***.com/questions/14594511/… 我已经尝试按照公认的答案所说的那样做。它没有影响。 .populate('subscriptions.show') 不会填充订阅数组上的 show 属性 不完全是重复的,因为它涉及更多一点。提供您想要的工作样本 【参考方案1】:

查看答案:https://***.com/a/28180427/3327857

  Car   .find()   .populate(
    path: 'partIds',
    model: 'Part',
    populate: 
      path: 'otherIds',
      model: 'Other'
       
 )

【讨论】:

【参考方案2】:

也许是一些代码,也可能是对您的方法的一些更正。你有点想要一个“manyToMany”类型的连接,你可以按如下方式进行:

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


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


var userSchema = new Schema(
  email: String,
  displayName: String,
  subscriptions: [ type: Schema.Types.ObjectId, ref: 'UserShow' ]
);

userShows = new Schema(
  show:  type: Schema.Types.ObjectId, Ref: 'Show' ,
  favorite:  type: Boolean, default: false 
);

var showSchema = new Schema(
  title: String,
  overview: String,
  subscribers: [ type: Schema.Types.ObjectId, ref: 'User' ],
  episodes: [
    title: String,
    firstAired: Date
  ]
);


var User = mongoose.model('User', userSchema);
var Show = mongoose.model('Show', showSchema);
var UserShow = mongoose.model('UserShow', userShows);

var user = new User(
  email: 'test@test.com',
  displayName: 'bill'
);

user.save(function(err,user) 

  var show = new Show(
    title: "Some Show",
    overview: "A show about some stuff."
  );

  show.subscribers.push( user._id );
  show.save(function(err,show) 
    var userShow = new UserShow( show: show._id );
    user.subscriptions.push( userShow._id );
    userShow.save(function(err,userShow) 
      user.save(function(err,user) 
        console.log( "done" );
        User.findOne( displayName: "bill" )
          .populate("subscriptions").exec(function(err,user) 

          async.forEach(user.subscriptions,function(subscription,callback) 
              Show.populate(
                subscription,
                 path: "show" ,
              function(err,output) 
                if (err) throw err;
                callback();
              );

          ,function(err) 
            console.log( JSON.stringify( user, undefined, 4) );
          );


        );
      );
    );
  );

);

这应该显示一个类似这样的填充响应:


    "_id": "53a7b8e60462281231f2aa18",
    "email": "test@test.com",
    "displayName": "bill",
    "__v": 1,
    "subscriptions": [
        
            "_id": "53a7b8e60462281231f2aa1a",
            "show": 
                "_id": "53a7b8e60462281231f2aa19",
                "title": "Some Show",
                "overview": "A show about some stuff.",
                "__v": 0,
                "episodes": [],
                "subscribers": [
                    "53a7b8e60462281231f2aa18"
                ]
            ,
            "__v": 0,
            "favorite": false
        
    ]


或者没有“manyToMany”也可以。请注意这里没有初始调用填充:

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


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


var userSchema = new Schema(
  email: String,
  displayName: String,
  subscriptions: [
    show: type: Schema.Types.ObjectId, ref: 'UserShow' ,
    favorite:  type: Boolean, default: false 
  ]
);


var showSchema = new Schema(
  title: String,
  overview: String,
  subscribers: [ type: Schema.Types.ObjectId, ref: 'User' ],
  episodes: [
    title: String,
    firstAired: Date
  ]
);


var User = mongoose.model('User', userSchema);
var Show = mongoose.model('Show', showSchema);

var user = new User(
  email: 'test@test.com',
  displayName: 'bill'
);

user.save(function(err,user) 

  var show = new Show(
    title: "Some Show",
    overview: "A show about some stuff."
  );

  show.subscribers.push( user._id );
  show.save(function(err,show) 
    user.subscriptions.push( show: show._id );
    user.save(function(err,user) 
        console.log( "done" );
        User.findOne( displayName: "bill" ).exec(function(err,user) 

          async.forEach(user.subscriptions,function(subscription,callback) 
              Show.populate(
                subscription,
                 path: "show" ,
              function(err,output) 
                if (err) throw err;
                callback();
              );

          ,function(err) 
            console.log( JSON.stringify( user, undefined, 4) );
          );


        );
    );
  );

);

【讨论】:

感谢您抽出宝贵时间提供该工作样本。我真的不认为这需要第三个模型。我以为你可以填充嵌套在对象中的引用,所以我强迫自己让它工作。 @LittleBill902 原因是从相关模型中的_id 值填充键。所以你这里的设计是经典的多对多。 @LittleBill902 为您添加了一个没有附加模型关系的示例 谢谢。实际上,在检查了您的第一个解决方案后,我通过您发布的新示例得出了这个结论。你帮了很多忙。

以上是关于Populate() ref 嵌套在对象数组中的主要内容,如果未能解决你的问题,请参考以下文章

mongoose#populate 在数组内的嵌套对象中返回 null

Mongoose Populate() 用对象替换数组

无法从 Mongoose 访问 populate()'d 对象的属性?

Mongoose - 使用 .populate 访问嵌套对象

Mongoose Populate Child ref 返回空数组

Mongoose 填充包含 ref 的对象数组