How to Populate data using Mongodb Aggregate framework?

不打扰是莪最后的温柔 提交于 2021-01-28 11:32:30

问题


I have a current MongoDB Aggregate framework pipeline from a previous question and I am unable to add populate query to grab user profile by id.

My code is below

Product.aggregate([
      {
        $group: {
          _id: {
            hub: "$hub",
            status: "$productStatus",
          },
          count: { $sum: 1 },
        },
      },
      {
        $group: {
          _id: "$_id.hub",
          counts: {
            $push: {
              k: "$_id.status",
              v: "$count",
            },
          },
        },
      },
      {
        $group: {
          _id: null,
          counts: {
            $push: {
              k: { $toString: "$_id" },
              v: "$counts",
            },
          },
        },
      },

      {
        $addFields: {
          counts: {
            $map: {
              input: "$counts",
              in: {
                $mergeObjects: [
                  "$$this",
                  { v: { $arrayToObject: "$$this.v" } },
                ],
              },
            },
          },
        },
      },
      {
        $replaceRoot: {
          newRoot: { $arrayToObject: "$counts" },
        },
      },
    ]);

and got the following result

[
  {
    "5fe75679e6f7a62ddaf5b2e9": {
      "in progress": 5,
      "Cancelled": 4,
      "return": 1,
      "on the way": 3,
      "pending": 13,
      "Delivered": 4
    }
  }
]

Expected Output

I need to grab user information from user collections using the hubId "5fe75679e6f7a62ddaf5b2e9" and expect a final result of the form below

[
    {
        "hub": {
            "photo": "avatar.jpg",
            "_id": "5fe75679e6f7a62ddaf5b2e9",
            "name": "Dhaka Branch",
            "phone": "34534543"
        },
        "statusCounts": {
            "in progress": 5,
            "Cancelled": 4,
            "return": 1,
            "on the way": 3,
            "pending": 13,
            "Delivered": 4
        }
    }
]

First id is user id and available in user collections.


回答1:


You need to tweak your aggregate pipeline a little bit and include new pipeline stage like $lookup that populates the hub

Product.aggregate([
    {  "$group": {
            "_id": {
                "hubId": "$hubId",
                "status": "$productStatus"
            },
            "count": { "$sum": 1 }
    } },
    { "$group": {
        "_id": "$_id.hubId",
        "statusCounts": {
            "$push": {
                "k": "$_id.status",
                "v": "$count"
            }
        }
    } },
    { "$lookup": {
        "fron": "users",
        "localField": "_id",
        "foreignField": "_id",
        "as": "user"
    } },
    { "$project": {
        "user": { "$arrayElemAt": ["$user", 0] },
        // "hub": { "$first": "$hub" },
        "statusCounts": { "$arrayToObject": "$statusCounts" }      
    } }
])

To project only some fields in the user profile, you can update your $lookup pipeline to have the form

{ "$lookup": {
    "from": "users",
    "let": { "userId": "$_id" },
    "pipeline": [
        { "$match": {
            "$expr": { "$eq": ["$_id", "$$userId"] }
        } },
        { "$project": { 
            "name": 1,
            "phone": 1, 
            "photo": 1 
        } }
    ],
    "as": "user"
} }


来源:https://stackoverflow.com/questions/65817859/how-to-populate-data-using-mongodb-aggregate-framework

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!