Заполнить вложенный массив в мангусте

Как я могу заполнить "компоненты" в примере документа:

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

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

  Project.findById(id).populate('pages').exec(function(err, project) {
    res.json(project);
  });
79 голосов | спросил Anton Shuvalov 7 +04002013-10-07T14:32:13+04:00312013bEurope/MoscowMon, 07 Oct 2013 14:32:13 +0400 2013, 14:32:13

8 ответов


0

Mongoose 4.5 поддерживает это

Project.find(query)
  .populate({ 
     path: 'pages',
     populate: {
       path: 'components',
       model: 'Component'
     } 
  })
  .exec(function(err, docs) {});
ответил Trinh Hoang Nhu 24 ThuEurope/Moscow2015-12-24T01:58:35+03:00Europe/Moscow12bEurope/MoscowThu, 24 Dec 2015 01:58:35 +0300 2015, 01:58:35
0

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

 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

ответил Anton Shuvalov 7 +04002013-10-07T18:40:25+04:00312013bEurope/MoscowMon, 07 Oct 2013 18:40:25 +0400 2013, 18:40:25
0

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

Project.findOne({name: req.query.name})
    .populate({
        path: 'threads',
        populate: {
            path: 'messages', 
            model: 'Message',
            populate: {
                path: 'user',
                model: 'User'
            }
        }
    })
ответил nikk wong 16 AMpSat, 16 Apr 2016 07:02:36 +030002Saturday 2016, 07:02:36
0

Вы можете заполнить несколько вложенных документов следующим образом.

   Project.find(query)
    .populate({ 
      path: 'pages',
      populate: [{
       path: 'components',
       model: 'Component'
      },{
        path: 'AnotherRef',
        model: 'AnotherRef',
        select: 'firstname lastname'
      }] 
   })
   .exec(function(err, docs) {});
ответил Shaul Hameed 29 AMpSun, 29 Apr 2018 11:22:19 +030022Sunday 2018, 11:22:19
0

Я обнаружил, что это очень полезно, создавая перо с привязкой перед хуком, чтобы заполнить глубокое отношение на уровне 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)
  }
}

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

ответил Travis S 21 stEurope/Moscowp30Europe/Moscow09bEurope/MoscowThu, 21 Sep 2017 14:59:10 +0300 2017, 14:59:10
0

Я нашел этот вопрос в другом вопросе, который был специфичен для KeystoneJS, но был помечен как дубликат. Если кто-то здесь может искать ответ Keystone, я так и сделал свой глубокий запрос в Keystone.

Двухуровневая популяция мангустов с использованием KeystoneJs [дубликаты]

exports.getStoreWithId = function (req, res) {
    Store.model
        .find()
        .populate({
            path: 'productTags productCategories',
            populate: {
                path: 'tags',
            },
        })
        .where('updateId', req.params.id)
        .exec(function (err, item) {
            if (err) return res.apiError('database error', err);
            // possibly more than one
            res.apiResponse({
                store: item,
            });
        });
};
ответил Leopold Kristjansson 15 42018vEurope/Moscow11bEurope/MoscowThu, 15 Nov 2018 01:32:04 +0300 2018, 01:32:04
0

Вы можете сделать это, используя $lookup агрегация также и, вероятно, лучший способ, как сейчас заполнение, вымирает из монго

Project.aggregate([
  { "$match": { "_id": mongoose.Types.ObjectId(id) } },
  { "$lookup": {
    "from": Pages.collection.name,
    "let": { "pages": "$pages" },
    "pipeline": [
      { "$match": { "$expr": { "$in": [ "$_id", "$$pages" ] } } },
      { "$lookup": {
        "from": Component.collection.name,
        "let": { "components": "$components" },
        "pipeline": [
          { "$match": { "$expr": { "$in": [ "$_id", "$$components" ] } } },
        ],
        "as": "components"
      }},
    ],
    "as": "pages"
  }}
])
ответил Anthony Winzlet 2 J000000Monday18 2018, 08:07:36
0

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

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);
});
ответил user4717265 26 MarpmThu, 26 Mar 2015 18:47:58 +03002015-03-26T18:47:58+03:0006 2015, 18:47:58

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132