我可以使用MongooseJS“填充”子文档数组中的属性吗?

时间:2013-11-05 17:59:07

标签: mongodb mongoose

关于mongoose的填充功能有很多SO问题,但我一直无法找到证据证明这是否可行,如果是,我做错了。

假设我正在制作一个博客。好极了。所有用户都可以撰写文章并在其他文章上发表评论。我选择以这种方式建模:

用户:

var UserSchema = new Schema({
    name: String,
    email: {
        type: String,
        unique: true
    }
});
mongoose.model('User', UserSchema);

嵌入评论的文章:

var ArticleSchema = new Schema({
    title: {
        type: String
    },
    createdBy: {
        type: Schema.ObjectId,
        ref: 'User'
    },
    comments: [
        commentsSchema
    ]
)};

var commentSchema = new Schema({
    message: {
        type: String
    },
    createdBy: {
        type: Schema.ObjectId,
        ref: 'User'
    }
});

mongoose.model('Article', ArticleSchema);

当我想加载文章时,我可以使用mongooseJS populate加载与其创建者的文章,如下所示:

Article
.findOne({_id: articleid})
.populate('createdBy', 'name email')
.exec(function(err,article) {
    console.log('Created by %s', article.createdBy.name); // This works, yay.
});

但是如果我还想使用populate加载THEIR创建者的评论,则comment.createdBy为null:

Article
.findOne({_id: articleid})
.populate('createdBy', 'name email')
.populate('comments.createdBy', 'name email') //am I doing this correctly?
.exec(function(err,article) {
    console.log('First comment by %s', article.comments[0].createdBy.name); // Error, createdBy is null.
});

使用最后一个版本,我可以看到article.comments [0] .createdBy为null。我已经验证了在db中注释具有createdBy的mongoose对象ID(并且它与现有用户匹配)。

这可能吗?
  - 如果是的话,我哪里错了?
  - 如果没有,有什么更好的方法来解决这个问题?像this one这样的MongoDB问题让我相信自己走在正确的轨道上,但也许错误地使用了猫鼬?

1 个答案:

答案 0 :(得分:1)

似乎不可能像这样填充双嵌套对象,可能仍然有办法实现它,但我没有碰到它。然而,另一种方法可以简单地这样做:

Article.findById(articleId, function(err, article) {
    if (err) {
        ...
    } else {
        Comment
            .find({_id: {$in: article.comments}})
            .populate('createdBy', 'name email')
            .exec(function(err, comments) {
                if (err) {
                    ...
                } else {
                    console.log('First comment by %s', comments[0].createdBy.name)
                }
            })
    }
})