Вкладывание мангуста
Я использую 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. Я там способ его заполнить?
Спасибо.
Ответы
Ответ 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)
За дополнительной информацией обратитесь к плагину .