Подтвердить что ты не робот

Вкладывание мангуста

Я использую Mongoose.js и не могу решить проблему с документом иерархии уровня 3.

Есть 2 способа сделать это.

Первый - без ссылок.

C = new Schema({
    'title': String,
});

B = new Schema({
    'title': String,
    'c': [C]
});

A = new Schema({
    'title': String,
    'b': [B]
});

Мне нужно показать запись C. Как я могу заполнить/найти его, зная только _id из C?

Я попытался использовать:

A.findOne({'b.c._id': req.params.c_id}, function(err, a){
    console.log(a);
});

Но я не знаю, как получить из returnet объект только c-объект, который мне нужен.

Второй при работе с refs:

C = new Schema({
    'title': String,
});

B = new Schema({
    'title': String,
    'c': [{ type: Schema.Types.ObjectId, ref: 'C' }]
});

A = new Schema({
    'title': String,
    'b': [{ type: Schema.Types.ObjectId, ref: 'B' }]
});

Как заполнить все записи B, C, чтобы получить иерархию?

Я пытался использовать что-то вроде этого:

A
.find({})
.populate('b')
.populate('b.c')
.exec(function(err, a){
    a.forEach(function(single_a){
        console.log('- ' + single_a.title);
        single_a.b.forEach(function(single_b){
            console.log('-- ' + single_b.title);
            single_b.c.forEach(function(single_c){
                console.log('--- ' + single_c.title);
            });
        });
    });
});

Но он вернет undefined для single_c.title. Я там способ его заполнить?

Спасибо.

4b9b3361

Ответ 1

в Mongoose 4 вы можете заполнять документы на нескольких уровнях:

Скажите, что у вас есть схема Пользователь, которая отслеживает друзей пользователя.

var userSchema = new Schema({
  name: String,
  friends: [{ type: ObjectId, ref: 'User' }]
});

populate() позволяет вам получить список друзей пользователя. Но что, если вы тоже хотели друзей друзей друзей? Укажите параметр populate, чтобы сообщить mongoose о заполнении массива friends всех друзей пользователя:

User.
  findOne({ name: 'Val' }).
  populate({
    path: 'friends',
    // Get friends of friends - populate the 'friends' array for every friend
    populate: { path: 'friends' }
  });

Взято из: http://mongoosejs.com/docs/populate.html#deep-populate

Ответ 2

Начиная с Mongoose 3.6 была добавлена ​​возможность рекурсивно заполнять связанные документы в запросе. Вот пример того, как вы можете это сделать:

 UserList.findById(listId)
         .populate('refUserListItems')
         .exec(function(err, doc){
             UserListItem.populate(doc.refUserListItems, {path:'refSuggestion'},
                   function(err, data){
                        console.log("User List data: %j", doc);
                        cb(null, doc);
                   }
             );     
          });           

В этом случае я заполняю массив id в 'refUserListItems' своими ссылочными документами. Результат запроса затем передается в другой запрос заполнения, который ссылается на поле исходного заполненного документа, который я хочу также заполнить - "refSuggestion".

Обратите внимание на второе (внутреннее) заполнение - это то, где происходит волшебство. Вы можете продолжать встраивать эти населенные пункты и использовать все больше и больше документов, пока вы не построите свой график так, как вам нужно.

Требуется немного времени, чтобы переварить, как это работает, но если вы работаете с ним, это имеет смысл.

Ответ 3

в Mongoose 4 вы можете заполнить многоуровневую форму (даже в другой базе данных или экземпляре)

A
.find({})
.populate({
  path: 'b', 
  model: 'B',
  populate: {
    path: 'c',
    model: 'C'
  }
})
.exec(function(err, a){});

Ответ 4

Я опаздываю на это, но я написал плагин Mongoose, из-за которого чрезвычайно просто выполнить глубокую модельную совокупность. Для вашего примера вы можете сделать это, чтобы заполнить b и c:

A.find({}, function (err, docs) {
  A.deepPopulate(docs, 'b.c', cb)
}

Вы также можете указать "Параметры заполнения мангуста" для каждого из заполненных путей, например:

A.deepPopulate(docs, 'b.c', {
  b: { 
    select: 'name'
  }
}, cb)

За дополнительной информацией обратитесь к плагину .