Mongoose populate sub-sub document

后端 未结 9 1940
深忆病人
深忆病人 2021-01-30 03:00

I have this setup in my MongoDB

Items:

title: String
comments: [] // of objectId\'s

Comments:

user: ObjectId()
item: Ob         


        
相关标签:
9条回答
  • 2021-01-30 03:02

    One more way (easier) to do this:

    Item
      .find({})
      .populate({
    	path:     'comments',			
    	populate: { path:  'user',
    		    model: 'users' }
      })
      .exec(function(err, data){
        if (err) return handleError(err);
        res.json(data);
    });

    0 讨论(0)
  • 2021-01-30 03:07

    To populate sub-sub document and populate from multiple schemas

    ProjectMetadata.findOne({id:req.params.prjId})
    .populate({
        path:'tasks',
        model:'task_metadata',
        populate:{
            path:'assigned_to',
            model:'users',
            select:'name employee_id -_id' // to select fields and remove _id field
    
        }
    })
    .populate({
        path:'client',
        model:'client'
    })
    .populate({
        path:'prjct_mgr',
        model:'users'
    })
    .populate({
        path:'acc_exec',
        model:'users'
    })
    .populate({
        path:'prj_type',
        model:'project_type'
    }).then ( // .. your thing
    

    or you can do it in following manner ..

       ProjectMetadata.findOne({id:req.params.prjId})
        .populate(
            [{
            path:'tasks',
            model:TaskMetadata,
            populate:[{
                path:'assigned_to',
                model:User,
                select:'name employee_id'
            },
            {
                path:'priority',
                model:Priority,
                select:'id title'
            }],
            select:"task_name id code assign_to stage priority_id"
        },
        {
            path:'client',
            model:Client,
            select:"client_name"
        },
        {
            path:'prjct_mgr',
            model:User,
            select:"name"
        },
        {
            path:'acc_exec',
            model:User,
            select:'name employee_id'
        },
        {
            path:'poc',
            model:User,
            select:'name employee_id'
        },
        {
            path:'prj_type',
            model:ProjectType,
            select:"type -_id"
        }
    
    ])
    

    I found the second method (of using array) more useful when I had to get multiple sub-sub documents of same parent.

    0 讨论(0)
  • 2021-01-30 03:12

    As a complete example calling populate on the result objects:

    Item.find({}).populate("comments").exec(function(err,data) {
        if (err) return handleError(err);
    
        async.forEach(data,function(item,callback) {
            User.populate(item.comments,{ "path": "user" },function(err,output) {
                if (err) throw err; // or do something
    
                callback();
            });
        }, function(err) {
            res.json(data);
        });
    
    });
    

    The call to .populate() in the form invoked from the model takes either a document or an array as it's first argument. So you loop through the returned results for each item and call populate this way on each "comments" array. The "path" tells the function what it is matching.

    This is done using the "async" version of forEach so it is non-blocking, but generally after all the manipulation all of the items in the response are not only populated with comments but the comments themselves have the related "user" details.

    0 讨论(0)
  • 2021-01-30 03:13

    I use this:

    .populate({
                path: 'pathName',
                populate: [
                    {
                        path: 'FirstSubPathName',
                        model: 'CorrespondingModel',
                    },
                    {
                        path: 'OtherSubPathName',
                        model: 'CorrespondingModel',
                    },
                    {
                        path: 'AnotherSubPathName',
                        model: 'CorrespondingModel',
                    },
                ]
            });
    

    it's the more easier way that i find to do this.I expect to help. :)

    0 讨论(0)
  • 2021-01-30 03:20

    Simpler

    Item
      .find({})
      .populate({
        path: 'comments.user',
        model: 'users' }
      })
      .exec(function(err, data){
        if (err) return handleError(err);
        res.json(data);
    });
    
    0 讨论(0)
  • 2021-01-30 03:21

    do it try it`s working find Project and get project related populate Task and Perticular Task User find

    db.Project.find()
    .populate({
        path: 'task',
        populate: { path: 'user_id'}
    })
    .exec(async(error,results)=>{
    
    })
    
    0 讨论(0)
提交回复
热议问题