2

I would like to populate a referenced model after an aggregation. So far I have this solution. I would like to populate the user object. It has name, email, phone fields.The aggregation is working perfectly, I get the desired result, but the user field is not getting populated. I have read so many similar solutions, but none of them were working unfortunately.

 exports.getResultToCompetition = asyncHandler(async (req, res, next) => {
  let competitionId = await Competition.findById(req.params.competitionId).select("_id");

  const result = await Result.aggregate([
    {
      // $match: { competition: mongoose.Types.ObjectId("competitionId") },
      $match: { competition: mongoose.Types.ObjectId(competitionId._id) },
    },
    {
      $project: {
        points: 1,
        kilogramms: 1,
        sector: 1,
        user: 1,
        competition: 1,
        place: 1,
      },
    },

    {
      $group: {
        _id: "$sector",
        res: { $push: "$$ROOT" },
      },
    },
    {
      $sort: {
        kilogramms: -1,
      },
    },
  ]);
  await Result.populate(result, { path: "user", select: "email name avatar flag" });

  res.status(200).json({ success: true, data: result });
});

What I also tried is, but not working.

await Result.populate(result, {
    path: "result",
    populate: {
      path: "res",
      model: "Result",
      populate: {
        path: "user",
        model: "User",
        select: "email name avatar flag",
      },
    },
  });

This is what I get in Postman.

{
    "success": true,
    "data": [
        {
            "_id": "A",
            "res": [
                {
                    "_id": "5eaeab6b2b9f246693a65659",
                    "points": 14,
                    "kilogramms": 14,
                    "place": 14,
                    "sector": "A",
                    "competition": "5eaeaa5448580765da33165a",
                 {
                    "_id": "5eaec018784ea96aa7daeebe",
                    "points": 23,
                    "kilogramms": 23,
                    "place": 12,
                    "sector": "A",
                    "competition": "5eaeaa5448580765da33165a",
           //Expected output includes the user object
                    "user": {
                      "_id": "5eaebf3471aab66a84ae01a4",
                       "name": "John Mayer",
                       "email": "[email protected]",
                       "phone": "123456789"
               }
            },
                },
                {
                    "_id": "5eaec018784ea96aa7daeebe",
                    "points": 23,
                    "kilogramms": 23,
                    "place": 12,
                    "sector": "A",
                    "competition": "5eaeaa5448580765da33165a",
                    "user": "5eaebf3471aab66a84ae01a4"
                },
                {
                    "_id": "5eaec028784ea96aa7daeebf",
                    "points": 12,
                    "kilogramms": 12,
                    "place": 14,
                    "sector": "A",
                    "competition": "5eaeaa5448580765da33165a",
                    "user": "5eaebf7f784ea96aa7daeeba"
                }
            ]
        },
        {
            "_id": "B",
            "res": [
                {
                    "_id": "5eaec03c784ea96aa7daeec0",
                    "points": 30,
                    "kilogramms": 34,
                    "place": 1,
                    "sector": "B",
                    "competition": "5eaeaa5448580765da33165a",
                    "user": "5eaebfa7784ea96aa7daeebb"
                },
                {
                    "_id": "5eaec04c784ea96aa7daeec1",
                    "points": 21,
                    "kilogramms": 20,
                    "place": 2,
                    "sector": "B",
                    "competition": "5eaeaa5448580765da33165a",
                    "user": "5eaebfd4784ea96aa7daeebc"
                },
                {
                    "_id": "5eaec05a784ea96aa7daeec2",
                    "points": 13,
                    "kilogramms": 13,
                    "place": 3,
                    "sector": "B",
                    "competition": "5eaeaa5448580765da33165a",
                    "user": "5eaebff5784ea96aa7daeebd"
                }
            ]
        }
    ]
}
7
  • Can you give sample documents and the expected output? Commented May 3, 2020 at 18:14
  • Please add to the question. results and users collections documents, and the expected output. Also what you get in postman is not necessary. Commented May 3, 2020 at 18:27
  • I have added the expected output to the first object Commented May 3, 2020 at 18:29
  • Ok, can you check my answer? I also cleared a few unnecessary lines. Commented May 3, 2020 at 18:36
  • Yes, Thank you :) I have removed the first line. Which was unnecessary. :) Commented May 3, 2020 at 18:39

1 Answer 1

1

First you don't need the following line:

let competitionId = await Competition.findById(req.params.competitionId).select("_id");

Also note that, you need to sort the kilogramms before $group, otherwise it has no effect.

Lastly, you can get the user info using $lookup like this:

exports.getResultToCompetition = asyncHandler(async (req, res, next) => {
  const data = await Result.aggregate([
    {
      $match: { competition: mongoose.Types.ObjectId(req.params.competitionId) },
    },
    {
      $project: {
        points: 1,
        kilogramms: 1,
        sector: 1,
        user: 1,
        competition: 1,
        place: 1,
      },
    },
    {
      $sort: {
        kilogramms: -1,
      },
    },
    {
      $lookup: {
        from: "users", // must be the PHYSICAL name of the collection
        localField: "user",
        foreignField: "_id",
        as: "user",
      },
    },
    {
      $addFields: {
        user: {
          $arrayElemAt: ["$user", 0],
        },
      },
    },
    {
      $group: {
        _id: "$sector",
        res: {
          $push: "$$ROOT",
        },
      },
    },
  ]);

  res.status(200).json({ success: true, data });
});

Playground

Output will be like this:

[
  {
    "_id": "A",
    "res": [
      {
        "_id": "5eaec018784ea96aa7daeebe",
        "competition": "5eaeaa5448580765da33165a",
        "kilogramms": 23,
        "place": 12,
        "points": 23,
        "sector": "A",
        "user": {
          "_id": "5eaebf3471aab66a84ae01a4",
          "email": "user2_email",
          "name": "User2",
          "phone": "user2_phone"
        }
      },
      {
        "_id": "5eaeab6b2b9f246693a65659",
        "competition": "5eaeaa5448580765da33165a",
        "kilogramms": 14,
        "place": 14,
        "points": 14,
        "sector": "A",
        "user": {
          "_id": "5ead24956ee84737c5910d06",
          "email": "user1_email",
          "name": "User1",
          "phone": "user1_phone"
        }
      },
      {
        "_id": "5eaec028784ea96aa7daeebf",
        "competition": "5eaeaa5448580765da33165a",
        "kilogramms": 12,
        "place": 14,
        "points": 12,
        "sector": "A",
        "user": {
          "_id": "5eaebf7f784ea96aa7daeeba",
          "email": "user3_email",
          "name": "User3",
          "phone": "user3_phone"
        }
      }
    ]
  },
  {
    "_id": "B",
    "res": [
      {
        "_id": "5eaec03c784ea96aa7daeec0",
        "competition": "5eaeaa5448580765da33165a",
        "kilogramms": 34,
        "place": 1,
        "points": 30,
        "sector": "B",
        "user": {
          "_id": "5eaebfa7784ea96aa7daeebb",
          "email": "user4_email",
          "name": "User4",
          "phone": "user4_phone"
        }
      },
      {
        "_id": "5eaec04c784ea96aa7daeec1",
        "competition": "5eaeaa5448580765da33165a",
        "kilogramms": 20,
        "place": 2,
        "points": 21,
        "sector": "B",
        "user": {
          "_id": "5eaebfd4784ea96aa7daeebc",
          "email": "user5_email",
          "name": "User5",
          "phone": "user1_phone"
        }
      },
      {
        "_id": "5eaec05a784ea96aa7daeec2",
        "competition": "5eaeaa5448580765da33165a",
        "kilogramms": 13,
        "place": 3,
        "points": 13,
        "sector": "B",
        "user": {
          "_id": "5eaebff5784ea96aa7daeebd",
          "email": "user6_email",
          "name": "User6",
          "phone": "user6_phone"
        }
      }
    ]
  }
]
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.