2015-06-02 4 views
1

У меня есть блок кода, как показано ниже. Я не мог найти, как этого добиться.
- У меня есть коллекция комнат в mongodb, а в документах этой коллекции есть массив идентификаторов пользователей. В каждой комнате может быть несколько пользователей.
- Поэтому я хочу найти имена пользователей, которые находятся в комнатах, которые включают мой идентификатор пользователя.NodeJs MongoDB Вложенные запросы - Запуск обратного вызова синхронно

DB коллекции:
Комнаты {RoomID: 1, пользователей: [99, 100]}, {RoomID: 2, пользователей: [99, 101]}
пользователи {_id: 99, имя: "Алекс" }, {_ ID: 100, имя: "Гарри"}, {_ ID: 101, имя: "Том"}

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 :, название: "Алекс, Гарри"}, {_id: 2 :, имя: "Алекс, Том"}]

Благодаря

ответ

1

Вы возвращаете res.json перед выполнением второго обратного вызова .find, поэтому он будет пустым. Вам нужно реструктурировать ждать всех асинхронными обратных вызовов, прежде чем ответить, например, так:

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(); 
     }); 
    } 

}); 
+0

Я хочу, чтобы иметь результат, как что: arrRooms: [{_id: 1 :, имя: «Алекс, Гарри»} , {_ id: 2 :, name: "Alex, Tom"}] Но ваш ответ не дает мне этого результата. Мне нужно запустить второй обратный вызов .find синхронно. –

+0

А, я вижу, у меня будет еще один ход. –

+0

@barisusanmaz Обновлено - это покрывает его? –

Смежные вопросы