Alerosa
Alerosa

Reputation: 698

Mongodb aggregation framework and nested $lookup

I'm trying to do a nested population by using the mongodb's aggregation framework and I have some troubles with it.

This is the initial data that I have:

[
  {
    _id: ObjectId('123'),
    profileId: ObjectId('456')
  },
  // ...other documents
]

I apply this aggregation pipeline to it so I can populate the profile field by using the profileId field:

MyModel.aggregate([
  {
    $lookup: {
      from: 'profiles',
      localField: 'profileId',
      foreignField: '_id',
      as: 'profile'
    }
  },
  {
    $project: {
      profile: {
        $arrayElemAt: [ '$profile', 0 ]
      },
      profileId: 1,
    }
  },
]

And this is the result:

[
  {
    _id: ObjectId('123'),
    profileId: ObjectId('456'),
    profile: {
      grades: [
        ObjectId('...'),
        ObjectId('...')
      ]
      // ... other props
    }
  }
  // ...other documents
]

Now I expand the pipeline by adding a $lookup to populate the grades inside each profile document:

MyModel.aggregate([
  {
    $lookup: {
      from: 'profiles',
      localField: 'profileId',
      foreignField: '_id',
      as: 'profile'
    }
  },
  {
    $project: {
      profile: {
        $arrayElemAt: [ '$profile', 0 ]
      },
      profileId: 1,
    }
  },
  {
    $lookup: {
      from: 'profile-grades',
      localField: 'profile._id',
      foreignField: 'profile',
      as: 'profile.grades'
    }
  }
]

This is the result so far:

[
  {
    _id: ObjectId('123'),
    profileId: ObjectId('456'),
    profile: {
      grades: [
        {
          studyLocationId: ObjectId('789'),
          // ... other props
        },
        // ... other grades
      ]
    }
  }
  // ...other documents
]

The final step that I'm not able to achieve is the population of each studyLocation inside the grades array.

Wanted result:

[
  {
    _id: ObjectId('123'),
    profileId: ObjectId('456'),
    profile: {
      grades: [
        {
          studyLocationId: ObjectId('789'),
          studyLocation: {
            _id: ObjectId('...'),
            // other props
          },
        },
        // ... other grades
      ]
    }
  }
  // ...
]

I've tried by adding another $lookup stage but without luck:

  {
    $lookup: {
      from: 'study-locations',
      localField: 'profile.grades.studyLocationId',
      foreignField: '_id',
      as: 'profile.grades.studyLocation'
    }
  }

This simply returns:

grades: {
   studyLocation: []
}

How should I do it? Is this even possible? Thank you!

Upvotes: 3

Views: 2310

Answers (1)

Shubham
Shubham

Reputation: 1426

If you are using mongodb3.4 this will work, for previous versions you need unwind operator on grades.

Upvotes: 1

Related Questions