IT박스

몽구스 : 깊은 인구 (밀집된 필드 채우기)

itboxs 2020. 12. 14. 07:58
반응형

몽구스 : 깊은 인구 (밀집된 필드 채우기)


나는 Category모델 있습니다 :

Category:
    ...
    articles: [{type:ObjectId, ref:'Article'}]

기사 모델에는 Account model.

Article:
    ...
    account: {type:ObjectId, ref:'Account'}

따라서 채워진 articles범주 모델은 다음과 같습니다.

{ //category
    articles: //this field is populated
     [ { account: 52386c14fbb3e9ef28000001, // I want this field to be populated
         date: Fri Sep 20 2013 00:00:00 GMT+0400 (MSK),
         title: 'Article 1' } ],
    title: 'Category 1' }

질문은 채워진 필드 ([articles])의 하위 필드 (계정)를 채우는 방법입니다. 지금 수행하는 방법은 다음과 같습니다.

globals.models.Category
    .find
        issue : req.params.id
        null
        sort:
            order: 1
    .populate("articles") # this populates only article field, article.account is not populated
    .exec (err, categories) ->
        console.log categories

여기에서 논의 된 내용을 알고 있습니다. Mongoose : 채워진 필드를 채우지 만 실제 솔루션을 찾을 수 없습니다.


Mongoose에는 이제 Model.populate깊은 연관을위한 새로운 방법 이 있습니다.

https://github.com/Automattic/mongoose/issues/1377#issuecomment-15911192


먼저, 몽구스 3을 4로 업데이트 한 다음 몽구스의 깊은 인구를 위해 가장 간단한 방법을 사용하십시오.

userId를 참조 ID로 갖는 블로그 스키마가 있고 사용자에서 스키마 검토를위한 참조 ID로 일부 검토가 있다고 가정합니다. 따라서 기본적으로 세 가지 스키마가 있습니다. 1. 블로그 2. 사용자 3. 검토

그리고이 블로그를 소유 한 사용자와 사용자 리뷰를 블로그에서 쿼리해야합니다. 따라서 결과를 다음과 같이 쿼리 할 수 ​​있습니다.

BlogModel
  .find({})
  .populate({
    path : 'userId',
    populate : {
      path : 'reviewId'
    }
  })
  .exec(function (err, res) {

  })

여러 수준에 걸쳐 채우기

사용자의 친구를 추적하는 사용자 스키마가 있다고 가정 해 보겠습니다.

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

채우기를 사용하면 사용자의 친구 목록을 가져올 수 있지만 사용자의 친구 친구도 원하면 어떻게해야합니까? 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


It might be a bit too late, but I wrote a Mongoose plugin to perform deep population at any arbitrary nested levels. With this plugin registered, you can populate category's articles and accounts with just a single line:

Category.deepPopulate(categories, 'articles.account', cb)

You can also specify populate options to control things like limit, select... for each populated path. Checkout the plugin documentation for more information.


Easiest way to accomplish this in 3.6 is to use Model.populate.

User.findById(user.id).select('-salt -hashedPassword').populate('favorites.things').exec(function(err, user){
    if ( err ) return res.json(400, err);

    Thing.populate(user.favorites.things, {
        path: 'creator'
        , select: '-salt -hashedPassword'
    }, function(err, things){
        if ( err ) return res.json(400, err);

        user.favorites.things = things;

        res.send(user.favorites);
    });
});

Sorry to burst your bubble, but there's not a directly supported solution to this. As for Github issue #601, it looks grim. According to the 3.6 release notes, it looks like the developers acknowledged the issue are happy with manual recursive/deep population.

So from the release notes, the recommended method is to nest populated calls in the callback, so in your exec() function, use categories.populate to further populate before sending a response.


globals.models.Category.find()
  .where('issue', req.params.id)
  .sort('order')
  .populate('articles')
  .exec(function(err, categories) {

    globals.models.Account.populate(categories, 'articles.account', function(err, deepResults){

      // deepResult is populated with all three relations
      console.log(deepResults[0].articles[0].account);

    });
});

The following example is inspired by the question asked @codephobia and populates two levels of many relationships. First fetch a user, populate its array of related orders and include each orderDetail.

user.model.findOne()
  .where('email', '***@****.com')
  .populate('orders')
  .exec(function(err, user) {

    orderDetail.model.populate(user, 'orders.orderDetails', function(err, results){

      // results -> user.orders[].orderDetails[] 
    });
});

This works fine in 3.8.8 but should work in 3.6.x.


This concept is deep Population. Here Calendar,Subscription,User,Apartment are mongoose ODM models in different levels

Calendar.find({}).populate({
      path: 'subscription_id',model: 'Subscription',
         populate: {path: 'user_id',model: 'User',
           populate: {path: 'apartment_id',model: 'Apartment',
              populate: {path: 'caterer_nonveg_id',
                          model: 'Caterer'}}}}).exec(function(err,data){ 
                          if(!err){
                             console.log('data all',data)
                           }
                           else{
                             console.log('err err err',err)
                            }
                   });

참고URL : https://stackoverflow.com/questions/18867628/mongoose-deep-population-populate-a-populated-field

반응형