如何使用Node.js查询MongoDb中的“join”集合?

时间:2014-04-30 11:19:28

标签: javascript node.js mongodb mongoose

我使用Node.js和mongoose来查询mongodb数据库。 这是非常简单的场景,但我无法弄清楚如何正确地做到这一点。

我有一个要查询的集合,然后给出结果,需要从另一个集合中获取对象以填充结果。代码示例如下:

q.exec( function (e, docs){
    if (e || !docs) {
        res.status(400);
        res.send("Error while processing request.\n"+ JSON.stringify(e, null, 4));
    }else{
         //do the JOIN here.
         var result = _(docs).map(
            function(doc){
                markModel.findOne(
                   {question_id: doc._id, user_id: user_id},
                   function (err, markDoc){
                     if (markDoc)
                        doc.mark = markDoc;
                   });
              //HOW and what to return here??
            });
         res.send(result);
    }
});

在上面的代码中,docs是第一个查询的结果;然后我需要为mark中的每个doc找到另一个集合中的docs,并将其附加到doc对象。因为第二个查询也是asyn被调用,所以我不知道应该在map()函数中返回什么,而不使用defer或promise等。

2 个答案:

答案 0 :(得分:0)

MongoDB是一个非关系型数据库,不支持连接 有关此需求,请查看data models documentation 另请参阅使用MapReducehttp://cookbook.mongodb.org/patterns/pivot/

的做法

答案 1 :(得分:-1)

Node.js行为是异步的,在获取结果集后将执行回调。在您的代码中,您正在对mongodb进行多次调用,这可以通过使用$ in构造来避免。 在循环中执行多个mongo调用是一个糟糕的设计,你无法确保何时返回或beak循环,因为你不知道何时将调用回调。为了避免这种情况,只需收集所有doc _id并使用$ in constru进行一次mongo调用。这样可以避免何时发送响应的混淆。如:

q.exec(function (e, docs) {
        if (e || !docs) {
            res.status(400);
            res.send("Error while processing request.\n" + JSON.stringify(e, 
                                                                 null, 4));
        } else {
            //do the JOIN here.     
            var docId = _(docs).map(
                function (doc) {
                    return parseInt(doc._id);
                });
            markModel.findOne({
                    question_id: {
                        $in: docId
                    },
                    user_id: user_id
                },
                function (err, markDoc) {
                    if (markDoc)
                        doc.mark = markDoc;
                    res.send(result); // send result
                });


        }
    });