Mongojs извлекает данные из двух коллекций и объединяет результат

Я новичок в mongodb и был бы очень признателен за помощь в решении этой проблемы, описанной ниже.

У меня есть две коллекции "пользователи" и "сумки". Схема сбора пользователей имеет {username, firstname, lastname}, а схема сбора сумок имеет {username, bagname, bagimage}.

При извлечении сумок пользователей я также хочу отображать имя и фамилию. Моя проблема в том, что я не могу правильно сформулировать запрос. Я использую драйвер nodejs и mongojs. Ниже мой запрос для получения всех сумок

  thmConfig.db.bags.find({status: "1"}).sort({$natural:-1}, function(err, data) 
{
        var bagList = '{"bags":[';


     if( err || !data) res.send('[{"status": "0"}]');
        else data.forEach( function(innerData) {
            console.log(innerData.username);
            bagList += JSON.stringify(innerData)+",";

                 /*
                   This is where I would lke to also append the firstname from the 
                users collection

                   */

        });

    console.log(bagList.slice(0,1));
    res.write(magList.slice(0,-1));
    res.end(']}');
});     

Я был бы очень признателен за любую помощь или указатели по этому поводу. У меня нет выбора при смене драйвера, поэтому я специально хочу реализовать это с помощью mongojs.

Спасибо и с уважением, Титаш


person Ami Titash    schedule 09.02.2013    source источник
comment
Вы тоже используете express.js? Какая версия? Также обратите внимание, что вызовы mongojs асинхронны. Таким образом, если вы хотите делать с ним дальнейшие вызовы (например, извлекать пользовательские данные для каждой сумки), вам может потребоваться выполнить некоторый рефакторинг.   -  person jsalonen    schedule 09.02.2013
comment
Да, я использую экспресс 3.0.0rc4. С помощью рефакторинга вы предлагаете перейти с mongojs на другой драйвер?   -  person Ami Titash    schedule 10.02.2013


Ответы (2)


Я не думаю, что у вас есть большой выбор, кроме чтения из коллекции пользователей и выполнения этой операции «присоединения» программно. Вы можете либо прочитать пользовательский документ для каждой сумки (внутри вашего цикла), либо заранее прочитать всю коллекцию пользователей в объект и выполнить поиск по имени пользователя.

person drorw    schedule 09.02.2013

Для этого вы можете использовать оператор $in.

Псевдокод(иш):

// get an array of bags matching your query
db.bags.find({status: "1"}).sort({$natural:-1}, function(err, bags) {
  // get a list of usernames from the bags:
  var usernames = bags.map(function(bag) { return bag.username; });

  // perform query on user table: find all users for which we have a bag
  db.users.find({ username : { $in : usernames } }, function(err, users) {
    // create a mapping of username -> first name for easy lookup
    var usernames = {};
    users.forEach(function(user) {
      usernames[user.username] = user.firstname;
    });

    // map first names to bags
    bags.forEach(function(bag) {
      bag.firstname = usernames[bag.username];
    });

    // done: return it as JSON (no need to build a JSON string ourselves)
    res.send({ bags : bags });
  });
});
person robertklep    schedule 15.05.2013