简体   繁体   中英

How to add populate with $lookup in aggregate using MongoDB (mongoose db)

I want to join one table with other. From the joined table I want to join another too. Is it possible. I will show it as an example. So that you will get a better idea. As am new to mongoDB, I don't know how to explain.

game

_id: ObjectId("5e6099a40c0ad78d5fedd69e")
line: 7
title: "Test Title"
attendance: "19812"
eventDate: "2020-02-22T00:30:00Z"
__v: 115
createdAt: 2020-03-22T22:39:47.559+00:00
updatedAt: 2020-09-08T02:09:26.430+00:00
count: 65
betCount: 34

bets

_id: ObjectId("5e72df1694d71f34dd561f6e")
isMatched: false
hasWon: true
user: ObjectId("5e6c5b08e1fc8ccde43b12fb")
game: ObjectId("5e6099a40c0ad78d5fedd69e")
amount: 30
createdAt: 2020-03-19T02:55:18.141+00:00
updatedAt: 2020-03-23T03:04:17.062+00:00
__v: 0

users

_id: ObjectId("5e6c5b08e1fc8ccde43b12fb")
name: "Jithin"
bio: "My Name is Jithin."
email: "jithin@gmail.com"
createdAt: 2020-03-12T21:55:49.024+00:00
updatedAt: 2020-09-09T04:59:13.769+00:00
__v: 0
currentAmount: 232
winnings: 4

I have used the below code to get result,

Games.aggregate([
    {
        $lookup: {
            from: "bets",
            localField: "_id",
            foreignField: "game",
            as: "bets"
        }
    }
],
(err, resp) => {
    if (err) {
        res.status(500).send(err);
    }
    
    res.status(200).json(resp);
});

But the output for the above code is,

{
    "_id": "5e609a4c0c0ad78d5fedd6a0",
    "line": 7,
    "title": "Test Title",
    "attendance": "19812",
    "eventDate": "2020-02-22T00:30:00Z",
    "__v": 115,
    "createdAt": "2020-03-22T22:39:47.559+00:00",
    "count": 65,
    "betCount": 34,
    "updatedAt": "2020-09-08T02:09:26.430+00:00",
    "bets": [
        {
            "_id": "5e72df1694d71f34dd561f6e",
            "isMatched": false,
            "hasWon": true,
            "user": "5e6c5b08e1fc8ccde43b12fb",
            "game": "5e6099a40c0ad78d5fedd69e",
            "amount": 30,
            "createdAt": "2020-03-19T02:55:18.141+00:00",
            "updatedAt": "2020-03-23T03:04:17.062+00:00",
            "__v": 0
        },
        ....
    ]
},
....

I want to join users with bets table. How to do that. Is there any way to do that. The final output should be like below,

{
    "_id": "5e609a4c0c0ad78d5fedd6a0",
    "line": 7,
    "title": "Test Title",
    "attendance": "19812",
    "eventDate": "2020-02-22T00:30:00Z",
    "__v": 115,
    "createdAt": "2020-03-22T22:39:47.559+00:00",
    "count": 65,
    "betCount": 34,
    "updatedAt": "2020-09-08T02:09:26.430+00:00",
    "bets": [
        {
            "_id": "5e72df1694d71f34dd561f6e",
            "isMatched": false,
            "hasWon": true,
            "user": [
                {
                    "_id": "5e6c5b08e1fc8ccde43b12fb",
                    "name": "Jithin",
                    "bio": "My Name is Jithin.",
                    "email": "jithin@gmail.com",
                    "createdAt": "2020-03-12T21:55:49.024+00:00",
                    "updatedAt": "2020-09-09T04:59:13.769+00:00",
                    "__v": 0,
                    "currentAmount": 232,
                    "winnings": 4
                },
                ....
            ]
            "game": "5e6099a40c0ad78d5fedd69e",
            "amount": 30,
            "createdAt": "2020-03-19T02:55:18.141+00:00",
            "updatedAt": "2020-03-23T03:04:17.062+00:00",
            "__v": 0
        },
        ....
    ]
},
....

Is there anyway to achieve the above result. I have no idea how to achieve this. I am new to node.js and mongodb. I am really stuck here.

You can use nested lookup,

  • $lookup using pipeline with bets collection
  • $match bets id
  • $lookup with user collection
Games.aggregate([
  {
    $lookup: {
      from: "bets",
      let: { id: "$_id" },
      pipeline: [
        { $match: { $expr: { $eq: ["$$id", "$game"] } } },
        {
          $lookup: {
            from: "user",
            localField: "user",
            foreignField: "_id",
            as: "user"
          }
        }
      ],
      as: "bets"
    }
  }
],
(err, resp) => {
    if (err) res.status(500).send(err);    
    res.status(200).json(resp);
});

Playground

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM