How to group data into an array, making a single object | MONGO + NODE

Asked

Viewed 459 times

0

I would like to fetch user data along with their linked portfolios in an array, however, is bringing as two arrays. And inside each wallet has an array of "entrances" where you would like to bring the type_sport referenced in it within each entry.

MONGO DB + NODE.JS

I have 4 collections

PEOPLE

"_id" : ObjectId("5d27b7ba5455a11eacdf164d"), 
"name" : {
     "first" : "Alexssander ", 
     "last" : "Leal"
}, 
"user" : {
     "active" : true, 
     "admin" : false, 
     "email" : "[email protected]", 
     "password" : "123456"
},  

WALLETS - With two user-related wallets

"_id" : ObjectId("5d27fbf95a298d4470416f33"), 
"members" : [
     {
         "creator" : true, 
         "people_id" : ObjectId("5d27b7ba5455a11eacdf164d")
     }
 ], 
 "name" : "Fundo de investimentos", 
 "type_coins_id" : ObjectId("5d1ebbb44a2b012e343ff48c"),
 "entrances" : [
     {
          "event" : "Arsenal x Manchester United",
          "stake" : 75,
          "type_sport" : ObjectId("5d1ebbb44a2b012e343ff568")
     },
     {
          "event" : "Bayer x Liverpool",
          "stake" : 75,
          "type_sport" : ObjectId("5d1ebbb44a2b012e343ff568")
     }
 ]

______________________________________________________________________________-

"_id" : ObjectId("5d280149b1e77444a013c86b"), 
 "members" : [
     {
         "creator" : true, 
         "people_id" : ObjectId("5d27b7ba5455a11eacdf164d")
     }
 ], 
 "name" : "Bolsa esportiva", 
 "type_coins_id" : ObjectId("5d1ebbb44a2b012e343ff48c"), 
 "entrances" : [
     {
          "event" : "Barcelona x Real Madrid",
          "stake" : 50,
          "type_sport" : ObjectId("5d1ebbb44a2b012e343ff568")
     },
     {
          "event" : "Santos x Flamengo",
          "stake" : 115,
          "type_sport" : ObjectId("5d1ebbb44a2b012e343ff568")
     }
 ]

TYPE_COINS

"_id" : ObjectId("5d1ebbb44a2b012e343ff48c"), 
"name" : "Real", 
"abbreviation" : "BRL", 

TYPE_SPORTS

 "_id" : ObjectId("5d1ebbb44a2b012e343ff568"),
 "name" : "Futebol"

MY QUERY CODE

let pipeline = [{
    $lookup: {
        from: 'wallets',
        localField: '_id',
        foreignField: 'members.people_id',
        as: 'wallets'
    },
}, {
    $unwind: { path: '$wallets' }
}, {
    $lookup: {
        from: 'type_coins',
        localField: 'wallets.type_coins_id',
        foreignField: '_id',
        as: 'wallets.type_coin'
    }
}, {
    $unwind: { path: '$wallets.type_coin'}
}];

However, they are bringing a duplicated user array, changing only the obj wallet of each position and duplicating records according to the amount of "entrances" within each wallet

EXPECTED RESULT

"_id" : ObjectId("5d27b7ba5455a11eacdf164d"), 
"name" : {
     "first" : "Alexssander ", 
     "last" : "Leal"
 }, 
 "user" : {
     "active" : true, 
     "admin" : false, 
     "email" : "[email protected]", 
     "password" : "123456"
 }, 
 wallets: [{
    "_id" : ObjectId("5d27fbf95a298d4470416f33"), 
    "members" : [{
         "creator" : true, 
         "people_id" : ObjectId("5d27b7ba5455a11eacdf164d")
     }], 
     "name" : "Wallet 1", 
     "type_coins_id" : {
         "_id" : ObjectId("5d1ebbb44a2b012e343ff48c"), 
         "name" : "Real", 
         "abbreviation" : "BRL", 
     }, 
     "entrances" : [{
          "event" : "Arsenal x Manchester United",
          "stake" : 75,
          "type_sport" : {
               "_id" : ObjectId("5d1ebbb44a2b012e343ff568"),
               "name" : "Futebol"
          }
     },
     {
          "event" : "Bayer x Liverpool",
          "stake" : 75,
          "type_sport" : {
               "_id" : ObjectId("5d1ebbb44a2b012e343ff568"),
               "name" : "Futebol"
          }
     }]
},
{
    "_id" : ObjectId("5d280149b1e77444a013c86b"), 
    "members" : [{
         "creator" : true, 
         "people_id" : ObjectId("5d27b7ba5455a11eacdf164d")
     }], 
     "name" : "Wallet 2", 
     "type_coins_id" : {
         "_id" : ObjectId("5d1ebbb44a2b012e343ff48c"), 
         "name" : "Real", 
         "abbreviation" : "BRL", 
     },
     "entrances" : [{
          "event" : "Barcelona x Real Madrid",
          "stake" : 50,
          "type_sport" : {
               "_id" : ObjectId("5d1ebbb44a2b012e343ff568"),
               "name" : "Futebol"
          }
     },
     {
          "event" : "Santos x Flamengo",
          "stake" : 115,
          "type_sport" : {
               "_id" : ObjectId("5d1ebbb44a2b012e343ff568"),
               "name" : "Futebol"
          }
     }] 
}]

1 answer

2

manual/pipeline referral

I hope it helps what I’ve done:

db.people.aggregate([{
$lookup: {
    from: 'wallets',
    let: { walletsID: '$_id' },
    pipeline: [
        {
            $match: {
                $expr: {
                    $in: [ '$$walletsID', '$members.people_id' ],
                }
            }
        },
        {
            $lookup: {
                from: 'type_coins',
                localField: 'type_coins_id',
                foreignField: '_id',
                as: 'type_coin'
            }
        }, 
       { $unwind: { 'path': '$entrances', preserveNullAndEmptyArrays': true } },
        {
            $lookup: {
                from: 'type_sports',
                localField: 'entrances.type_sport',
                foreignField: '_id',
                as: 'entrances.type_sport'
            }
        }, 
        { $unwind: { 'path': '$entrances.type_sport', 'preserveNullAndEmptyArrays': true } },
        {
            $group: { 
                _id: "$_id",
                name:{$first: "$name"},
                members:{$first: "$members"},
                type_coin:{$first: "$type_coin"},
                entrances:{$addToSet: "$entrances"}
            }
        },
        { $unwind: { 'path': '$type_coin', 'preserveNullAndEmptyArrays': true } },
    ],
    as: 'wallets'
}}])

Upshot:

{
"_id" : ObjectId("5d27b7ba5455a11eacdf164d"),
"name" : {
    "first" : "Alexssander ",
    "last" : "Leal"
},
"user" : {
    "active" : true,
    "admin" : false,
    "email" : "[email protected]",
    "password" : "123456"
},
"wallets" : [
    {
        "_id" : ObjectId("5d280149b1e77444a013c86b"),
        "name" : "Bolsa esportiva",
        "members" : [
            {
                "creator" : true,
                "people_id" : ObjectId("5d27b7ba5455a11eacdf164d")
            }
        ],
        "type_coin" : {
            "_id" : ObjectId("5d1ebbb44a2b012e343ff48c"),
            "name" : "Real",
            "abbreviation" : "BRL"
        },
        "entrances" : [
            {
                "event" : "Santos x Flamengo",
                "stake" : 115,
                "type_sport" : {
                    "_id" : ObjectId("5d1ebbb44a2b012e343ff568"),
                    "name" : "Futebol"
                }
            },
            {
                "event" : "Barcelona x Real Madrid",
                "stake" : 50,
                "type_sport" : {
                    "_id" : ObjectId("5d1ebbb44a2b012e343ff568"),
                    "name" : "Futebol"
                }
            }
        ]
    },
    {
        "_id" : ObjectId("5d27fbf95a298d4470416f33"),
        "name" : "Fundo de investimentos",
        "members" : [
            {
                "creator" : true,
                "people_id" : ObjectId("5d27b7ba5455a11eacdf164d")
            }
        ],
        "type_coin" : {
            "_id" : ObjectId("5d1ebbb44a2b012e343ff48c"),
            "name" : "Real",
            "abbreviation" : "BRL"
        },
        "entrances" : [
            {
                "event" : "Bayer x Liverpool",
                "stake" : 75,
                "type_sport" : {
                    "_id" : ObjectId("5d1ebbb44a2b012e343ff568"),
                    "name" : "Futebol"
                }
            },
            {
                "event" : "Arsenal x Manchester United",
                "stake" : 75,
                "type_sport" : {
                    "_id" : ObjectId("5d1ebbb44a2b012e343ff568"),
                    "name" : "Futebol"
                }
            }
        ]
    }
]}
  • Show, it worked perfectly, thank you very much! Now I have another problem, maybe you can help me too.. I have an array inside each 'Wallet' which is called 'entrances' and inside each entry has an id representing which sport that matches that entry, and I would like to take in the collection of 'type_sports' the sport data of each entry.

  • 1

    Edit the post and add to others

  • Prompt, I edited with what I’m doubting above haha, thank you very much for the help and attention :D

  • See if it helps.. That’s it.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.