Search code examples
node.jsmongodbmongoosecollectionspopulate

How can I get data from a child collection in mongodb?


I need to populate 'tasks' in the following json string.

{
    "sectionname": "Section1",
    "tasks": [],
    "_id": "5d46e5c4d2e87911d8d4d42c",
    "projectid": "5d46d42333aecb0b6aa3f2ca",
    "userid": "5d46b54635bb9e05b9d33528",
    "time": "2019-08-04T14:03:48.953Z",
    "__v": 0
},

It currently consists of 3 collections (excluding the User Account collection)

  1. Project
  2. Section
  3. Task

I get data from Section and Project with a simple Find request. Eg:

userProjectSections.find({userid: req.user, projectid: req.params.id})

I then decided to add .populate('tasks'), however it didn't change anything. Tasks are still empty [ ].

Here's the full models.

const userProjects = mongoose.Schema({
    _id: mongoose.Schema.Types.ObjectId,
    time : { type : Date, default: Date.now },
    complete : { type : Boolean, default: false },
    userid: {type: String, ref: 'user'},
    projectname: {type: String, default: 'New Project'}
});

module.exports = mongoose.model('Projects', userProjects);

const userProjectSections = mongoose.Schema({
    _id: mongoose.Schema.Types.ObjectId,
    time : { type : Date, default: Date.now },
    complete : { type : Boolean, default: false },
    userid: {type: String, ref: 'user'},
    projectid: {type: String, ref: 'Projects'},
    sectionname: {type: String, default: 'New Section'},
    tasks: [{ type: Schema.ObjectId, ref: 'SectionTasks' }]
});

module.exports = mongoose.model('ProjectSection', userProjectSections);

const userSectionTasks = mongoose.Schema({
    _id: mongoose.Schema.Types.ObjectId,
    time : { type : Date, default: Date.now },
    complete : { type : Boolean, default: false },
    userid: {type: String, ref: 'user'},
    projectid: {type: String, ref: 'Projects'},
    sectionid: {type: String, ref: 'ProjectSection'},
    task: {type: String, default: 'New task'}
});

module.exports = mongoose.model('SectionTasks', userSectionTasks);

Theoretically, I could write another API call from my React frontend, but I'd prefer to get the data from a single request and include tasks.


Solution

  • Ended up killing const userSectionTasks and instead added an extra array, Tasks into const userProjectSections, like so

    tasks: [{
            _id: mongoose.Schema.Types.ObjectId,
            task: String,
            postedBy: {
                type: mongoose.Schema.Types.ObjectId,
                ref: 'user'
            }
        }]
    
    

    And now I can simply use $addToSet to add new tasks to the section.

    Cheers!