No, you cannot call .populate() before .aggregate() , and there is a very good reason why you cannot. But there are different approaches that you can take.
The .populate() method works on the "client side", where the base code actually performs additional requests (or, more precisely, the $in request) to "search" for the specified element (s) from the reference collection.
Unlike .aggregate() , the server-side operation is used, so you can’t basically manipulate the client-side content and then provide this data for subsequent stages of the aggregation pipeline. All this should be present in the collection in which you work.
A more convenient approach can be obtained with MongoDB 3.2 and later using the $lookup operation. It is also probably best to handle from the User collection in this case to narrow down the selection:
User.aggregate( [
Basically, this will include the new “rating” field in the User object as an “array” of elements that match the “search” for another collection:
{ "userID": "abc", "age": 21, "score": [{ "userID": "abc", "score": 42,
The result is always an array, since the total expected use is the “left join” of a possible one-to-many relationship. If the result is not consistent, it is simply an empty array.
To use content, just work with the array. For example, you can use the $arrayElemAt operator to simply get the only first element of an array in any future operations. And then you can just use the content like any normal inline field:
{ "$project": { "userID": 1, "age": 1, "score": { "$arrayElemAt": [ "$score", 0 ] } }}
If you do not have MongoDB 3.2 available, then your other request processing option, limited by the relations of another collection, should first get the results from this collection and then use $in to filter by the second:
Thus, having received a list of valid users from another collection for the client, and then loading them into another collection in the request, this may be the same as in previous releases.