Вложенный запрос Mongoose в Model по полю его ссылочной модели

Похоже, в этой теме много вопросов Q/A по stackoverflow, но я не могу найти точный ответ в любом месте.

Что у меня есть:

У меня есть модели компании и человека:

var mongoose = require('mongoose');
var PersonSchema = new mongoose.Schema{
                        name: String, 
                        lastname: String};

// company has a reference to Person
var CompanySchema = new mongoose.Schema{
                        name: String, 
                        founder: {type:Schema.ObjectId, ref:Person}};

Что мне нужно:

Найти все компании, которые основали люди с фамилией "Робертсон"

То, что я пробовал:

Company.find({'founder.id': 'Robertson'}, function(err, companies){
    console.log(companies); // getting an empty array
});

Затем я понял, что Person не встроен, но упоминается, поэтому я использовал populate, чтобы заполнить основатель-Person, а затем попытался использовать find с именем "Robertson"

// 1. retrieve all companies
// 2. populate their founders
// 3. find 'Robertson' lastname in populated Companies
Company.find({}).populate('founder')
       .find({'founder.lastname': 'Robertson'})
       .exec(function(err, companies) {
        console.log(companies); // getting an empty array again
    });

Я все еще могу запрашивать компании с идентификатором Person как String. Но это не совсем то, что я хочу, поскольку вы можете понять

Company.find({'founder': '525cf76f919dc8010f00000d'}, function(err, companies){
    console.log(companies); // this works
});

Ответы

Ответ 1

Вы не можете сделать это в одном запросе, потому что MongoDB не поддерживает соединения. Вместо этого вам нужно разбить его на пару шагов:

// Get the _ids of people with the last name of Robertson.
Person.find({lastname: 'Robertson'}, {_id: 1}, function(err, docs) {

    // Map the docs into an array of just the _ids
    var ids = docs.map(function(doc) { return doc._id; });

    // Get the companies whose founders are in that set.
    Company.find({founder: {$in: ids}}, function(err, docs) {
        // docs contains your answer
    });
});

Ответ 2

В случае, если кто-то столкнется с этим в более поздние времена, Mongoose теперь поддерживает объединение, как функциональность с функцией Populate.

Из документации Mongoose:

Story.
findOne({ title: 'Casino Royale' }).
populate('author').
exec(function (err, story) {
  if (err) return handleError(err);
  console.log('The author is %s', story.author.name);
  // prints "The author is Ian Fleming"

});

http://mongoosejs.com/docs/populate.html