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

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

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

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

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

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

我正在使用的完整测试文件源 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
  }]
}

【问题讨论】:

标签: javascript node.js mongodb mongoose


【解决方案1】:

查看答案:https://stackoverflow.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 为您添加了一个没有附加模型关系的示例
    • 谢谢。实际上,在检查了您的第一个解决方案后,我通过您发布的新示例得出了这个结论。你帮了很多忙。
    猜你喜欢
    • 2017-11-17
    • 2014-08-15
    • 2013-05-22
    • 1970-01-01
    • 1970-01-01
    • 2019-08-11
    • 1970-01-01
    • 2022-01-08
    • 2020-03-11
    相关资源
    最近更新 更多