NodeJs MongoDB嵌套查询 - 同步运行回调

时间:2015-06-02 09:02:16

标签: javascript node.js mongodb mongoskin

我有一个代码块,如下所示。我找不到如何做到这一点 - 我在mongodb中有房间集合,这个集合中的文档包括用户id数组。每个房间可以有多个用户 - 所以我想找到包含我的用户ID的房间中的用户名。

数据库集合:
房间{roomId:1,用户:[99,100]},{roomId:2,用户:[99,101]}
用户{_ id:99,名称:“Alex”},{_ id:100,名称:“Harry”},{_ id:101,名称:“Tom”}

var userId = 99;
var arrUserIds = [];
var arrRooms = [];
var strUserNames = "";
db.collection("rooms").find({"users.userId":userId}).toArray(function(err, rooms) {

    for (var i=0; i<rooms.length; i++) {
        arrUserIds = [];

        for(var j=0; j<rooms[i].users.length; j++){
            arrUserIds.push(new BSON.ObjectID(rooms[i].users[j].userId));   
        }

        db.collection('users').find({"_id": {$in: arrUserIds}}).toArray(function(err, users) {
            strUserNames = users.map(function(elem){return elem.name;}).join(", ");
            arrRooms.push({_id:rooms[i].roomId, name:strUserNames });
        });

    }

    res.json({rooms:arrRooms});
});

我希望得到这样的结果:
arrRooms:[{_ id:1:,名称:“Alex,Harry”},{_ id:2:,名称:“Alex,Tom”}}

由于

1 个答案:

答案 0 :(得分:1)

你在第二个.find回调执行之前返回res.json,所以它将为空。您需要重新构建以在响应之前等待所有异步回调,如下所示:

var userId = 99;
var arrRooms = [];
var strUserNames = "";

db.collection("rooms").find({"users.userId":userId}).toArray(function(err, rooms) {

    var completed = 0;
    var complete = function() {
        completed++;
        if (completed === rooms.length - 1) {
            res.json({rooms:arrRooms});
        }
    }


    for (var i=0; i<rooms.length; i++) {
        var arrUserIds = [];
        var roomId = rooms[i].roomId;

        for(var j=0; j<rooms[i].users.length; j++){
            arrUserIds.push(new BSON.ObjectID(rooms[i].users[j].userId));   
        }

        db.collection('users').find({"_id": {$in: arrUserIds}}).toArray(function(err, users) {
            strUserNames = users.map(function(elem){return elem.name;}).join(", ");
            arrRooms.push({_id:roomId, name:strUserNames });

            complete();
        });
    }

});