【问题标题】:Mongoose: populate method doesn't properly workMongoose:填充方法无法正常工作
【发布时间】:2015-07-07 08:01:40
【问题描述】:

我可以在这里使用一些帮助,但我无法弄清楚为什么 populate 方法不能按预期工作。 我想为一些里面有人的“房间”建模。

var PersonSchema = new Schema({
    _id   : Schema.ObjectId,
    name  : String,
});
var Person = mongoose.model('Person', PersonSchema, 'Person');

var RoomSchema = new Schema({
      _id    : Schema.ObjectId, 
      name : String,
      People : [{ type: Schema.ObjectId, ref: 'Person' }],
});
var Room = mongoose.model('Room', RoomSchema, 'Room');

所以,我有一个包含一个条目的 Person 集合:

{ 
"name" : "person1", 
"_id" : ObjectId("4f9e5bb68bcd69fb0c000002") 
}

还有一个带有一个条目的 Room 集合:

{ 
"_id" : ObjectId("4f9e5bb68bcd69fb0c000001"), 
"name" : "room1", 
"People" : [ ObjectId("4f9e5bb68bcd69fb0c000002") ] 
}

当我尝试执行这个查询时:

Room.findOne({ 'name': 'room1' }).populate('People').run(function (err, result) {
  if(err) console.log(err);
  console.log(result);
});

我得到输出:

{ _id: 4f9e5bb68bcd69fb0c000001,
  name: 'room1',
  People: []
}

为什么 Mongoose 不填充人员字段?我只是不明白可能出了什么问题。

【问题讨论】:

  • 我一直在搜索,似乎问题出在我强制集合名称的事实: var Person = mongoose.model('Person', PersonSchema, 'Person');如果我像这样更改模型: var Person = mongoose.model('Person', PersonSchema);一切正常。但这并不能解决我的问题,因为我确实需要强制收集名称...

标签: node.js mongodb mongoose


【解决方案1】:

这个问题是 2.x 版本的 mongoose 中的一个错误。已修复:https://github.com/LearnBoost/mongoose/issues/877

【讨论】:

    【解决方案2】:

    因为 mongoose 不会“加入”数据(我认为您正在尝试这样做)。

    你想做的是这样的(注意这是评论和博文)

    Schema

    var Comments = new Schema({
        title     : String
      , body      : String
      , date      : Date
    });
    
    var BlogPost = new Schema({
        author    : ObjectId
      , title     : String
      , body      : String
      , buf       : Buffer
      , date      : Date
      , comments  : [Comments]
      , meta      : {
          votes : Number
        , favs  : Number
      }
    });
    

    然后创建一个博客模型并设置 cmets(在您的示例中为房间中的人)

    // retrieve my model
    var BlogPost = mongoose.model('BlogPost');
    
    // create a blog post
    var post = new BlogPost();
    
    // create a comment
    post.comments.push({ title: 'My comment' });
    
    post.save(function (err) {
      if (!err) console.log('Success!');
    });
    

    如果您不想嵌入文档,您可以从该回调中进行搜索。例如,这是我从推文作者那里获取用户名的咖啡脚本示例:

    ModelTweets.find {}, (err, tweetResults) ->
        if tweetResults.length == 0
          res.render 'tweets/index', tweets: 0
        else
          # Get the Author for each tweet
          tweetResults.forEach (tweetInfo) ->
            count++
            ModelUser.findOne {'_id': tweetInfo.author}, (err, userInfo) ->
              tweets.push {id: tweetInfo._id, tweet: tweetInfo.tweet, created_at: tweetInfo.created_at, author: userInfo.username}
    
            if count == tweetResults.length
              res.render 'tweets/index', {tweets: tweets || {}}
    

    这应该让你走上正轨:)

    【讨论】:

    • 感谢您的回答!是的,你是对的,我尝试“加入”数据。我知道在 mongodb 中没有 SQL join 之类的东西,但是有可能“链接”到其他文档。我可能误解了填充方法(mongoosejs.com/docs/populate.html),但我认为这是一种“模拟加入”的方法,而无需麻烦地提出子请求?我错了吗?
    猜你喜欢
    • 2017-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-26
    • 2021-06-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多