如何在MongoDB中检索“相关”文档?

时间:2013-03-04 02:49:48

标签: javascript node.js mongodb express mongoskin

我正在为MongoDB使用node.js,express和MongoSkin驱动程序。

我正在尝试在我的博客应用程序中呈现一个显示博客帖子列表的视图。每篇文章都引用了作者ID。我正在尝试为每个帖子进行第二次查询,以获取每个参考的完整作者文档。异步的一切让我感到困惑。

在获取博客帖子列表的回调中,我正在遍历每个帖子并进行第二次调用以获取相关用户。我不知道如何在所有帖子都添加了作者文档后才呈现视图。我甚至不确定我是否做到了这一点。如何引用其他文档来完成我想要做的事情?

// getPageOfPosts is a custom helper that accepts the page number and number of items to retrieve.
db.collection('blogPosts').getPageOfPosts(req.param('page') || 1, 3, function (err, blogPosts) {
    if (err) req.next(err);
    blogPosts.forEach(function (blogPost) {
        db.collection('users').findOne({ _id: blogPost.authorId }, function (err, user) {
            if (err) req.next(err);
            blogPost.author = user;
        });
    });
    var viewModel = {
        posts: blogPosts
    };
    res.render('blog/index', viewModel);
});

1 个答案:

答案 0 :(得分:2)

您可以在nodejs https://github.com/caolan/async中使用异步库。这有助于以串行或并行方式执行一组函数,一旦完成所有这些函数,就会调用最终回调来执行渲染部分。


按问题编辑编辑:

这是一个很好的建议,工作得很漂亮!方法如下:

db.collection('blogPosts').getPage(req.param('page') || 1, 3, function (err, blogPosts) {
    if (err) req.next(err);
    var addUsersArray = [];
    blogPosts.forEach(function (blogPost) {
        addUsersArray.push(function (callback) {
            db.collection('users').findOne({ _id: blogPost.author }, function (err, user) {
                if (err) callback(err);
                blogPost.author = user;
                callback(null, blogPost);
            });
        });
    });
    async.parallel(addUsersArray, function (err, blogPosts) {
        if (err) req.next(err);
        var viewModel = {
            posts: blogPosts
        };
        res.renderView('blog/index', viewModel);
    });
});

以下也适用

db.collection('blogPosts').getPageOfPosts(req.param('page') || 1, 3, function (err, blogPosts) {
if (err) req.next(err);
async.each(blogPosts,function (blogPost,cb) {
    db.collection('users').findOne({ _id: blogPost.authorId }, function (err, user) {
        if (err) req.next(err);
        blogPost.author = user;
        cb(err);
    });
},function(error)
{
    var viewModel = {
    posts: blogPosts
    };
    res.render('blog/index', viewModel);
});

});