2013-10-07 4 views
58

Как я могу заполнить «компоненты» в примере документа:Populate Вложенный массив в мангуста

{ 
    "__v": 1, 
    "_id": "5252875356f64d6d28000001", 
    "pages": [ 
     { 
     "__v": 1, 
     "_id": "5252875a56f64d6d28000002", 
     "page": { 
      "components": [ 
      "525287a01877a68528000001" 
      ] 
     } 
     } 
    ], 
    "author": "Book Author", 
    "title": "Book Title" 
    } 

Это мой JS, где я получаю документ по Мангуста:

Project.findById(id).populate('pages').exec(function(err, project) { 
    res.json(project); 
    }); 
+0

Теперь он пуст? Какие результаты вы получаете? – WiredPrairie

+2

если я пишу '... populate ('pages pages.page.components'). Exec ...' Я получаю то же самое, что указано в примере документа. Ничего не изменилось. –

ответ

103

Mongoose 4,5 поддерживают эту

Project.find(query) 
    .populate({ 
    path: 'pages', 
    populate: { 
     path: 'components', 
     model: 'Component' 
    } 
    }) 
    .exec(function(err, docs) {}); 
+6

Удивительный - настолько чище! Это современный и правильный ответ. [Документировано здесь] (http://mongoosejs.com/docs/populate.html#deep-populate). – isTravis

+1

Mongoose <4.5 не работает для этого. – NgaNguyenDuy

+0

@NgaNguyenDuy https://github.com/Automattic/mongoose/wiki/4.0-Release-Notes говорит, что эта функция уже существует с 4.0. Вы можете получить неправильный запрос. –

94

Это работает для меня:

Project.find(query) 
    .lean() 
    .populate({ path: 'pages' }) 
    .exec(function(err, docs) { 

    var options = { 
     path: 'pages.components', 
     model: 'Component' 
    }; 

    if (err) return res.json(500); 
    Project.populate(docs, options, function (err, projects) { 
     res.json(projects); 
    }); 
    }); 

Документация: Model.populate

+9

«Модель:« Компонент »действительно важна! –

+1

@Totty Точно, это помогает мангусте понять данные, которые необходимо использовать для заполнения ref. –

+3

Но не следует, потому что, когда я определяю ref, я также определяю модель, это не действительно СУХОЙ. В любом случае, спасибо, это работает;) –

-2

Удалите документы ссылки

if (err) { 
    return res.json(500); 
} 
Project.populate(docs, options, function (err, projects) { 
    res.json(projects); 
}); 

Это работает для меня.

if (err) { 
    return res.json(500); 
} 
Project.populate(options, function (err, projects) { 
    res.json(projects); 
}); 
16

Как уже отмечалось, Mongoose 4 поддерживает это. Очень важно отметить, что вы можете рекурсию глубже, чем на один уровень тоже, в случае необходимости, хотя это не отмечено в документации:

Project.findOne({name: req.query.name}) 
    .populate({ 
     path: 'threads', 
     populate: { 
      path: 'messages' 
      , model: 'Message' 
      , populate: { 
       path: 'user' 
       , model: 'User' 
      } 
     } 
    }) 
+0

Спасибо nikk! ваше предложение работало как шарм. – user752746

2

Я нашел это очень полезно, создавая feathersjs до крючка для заполнения 2 реф уровень глубокий отношение. Модели мангуст просто

tables = new Schema({ 
    .. 
    tableTypesB: { type: Schema.Types.ObjectId, ref: 'tableTypesB' }, 
    .. 
} 
tableTypesB = new Schema({ 
    .. 
    tableType: { type: Schema.Types.ObjectId, ref: 'tableTypes' }, 
    .. 
} 

затем в feathersjs перед тем крючке:

module.exports = function(options = {}) { 
    return function populateTables(hook) { 
    hook.params.query.$populate = { 
     path: 'tableTypesB', 
     populate: { path: 'tableType' } 
    } 

    return Promise.resolve(hook) 
    } 
} 

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

+0

Если не беспокоиться о перезаписывании запрошенного запроса $ populate. В этом случае вы должны использовать hook.params.query. $ Populate = Object.assign (hook.params.query. $ Populate || {}, {/ * новый населенный объект здесь * /}) –

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