Joshua Varghese
Joshua Varghese

Reputation: 5202

Mongodb Merging/Joining Nested Objects

I've looked up a lot to find a solution. But I am unable to form a solution to my problem.
I have two MongoDB (Node.JS) collections: user & statistics. I'm trying to merge the results through aggregate.

Here are the structures of the collections:
user

{
    _id: 602baa4e38e6de8e08737557,
    id: '50496531082300001',
    data: {
        avatar: 'https://example.com/test.png',
        username: 'John Doe',                                                                                                                                                                                                            
    }
},
{
    _id: 602baa4602baa4e38e6de58,
    id: '50496531082300002',
    data: {
        avatar: 'https://example.com/test2.png',
        username: 'Rebecca Jones',                                                                                                                                                                                                            
    }
},

statistics

{
    _id: 4e38e6de8e0873755778755,
    id: '456789987654345678',
    data: {
        members: {
            '50496531082300001' : {
                messages: 20,
                emails: 200
            },
            '50496531082300002' : {
                messages: 40,
                emails: 400
            },
        }
    }
},

So I'm trying to merge the data from user and the key-pair value data.members from statistics.
But the issue here is, id of user has to match keys of data.members from statistics, and I cant find a way to do it.

Expected Output

'50496531082300001' : {
    messages: 20,
    emails: 200,
    avatar: 'https://example.com/test.png',
    username: 'John Doe'
},
'50496531082300002' : {
    messages: 40,
    emails: 400,
    avatar: 'https://example.com/test2.png',
    username: 'Rebecca Jones',
},

Upvotes: 1

Views: 164

Answers (1)

turivishal
turivishal

Reputation: 36104

  • $addFields to convert members object to array using $objectToArray, it will convert key-value format
  • $unwind deconstruct members array
  • $lookup to join users collection
  • $group by _id and reconstruct members array, get first element from user and data, merge with current object using $mergeObjects
  • convert members array to object using $arrayToObjects
db.statistics.aggregate([
  { $addFields: { "data.members": { $objectToArray: "$data.members" } } },
  { $unwind: "$data.members" },
  {
    $lookup: {
      from: "users",
      localField: "data.members.k",
      foreignField: "id",
      as: "user"
    }
  },
  {
    $group: {
      _id: "$_id",
      members: {
        $push: {
          k: "$data.members.k",
          v: {
            $mergeObjects: [
              "$data.members.v",
              { $arrayElemAt: ["$user.data", 0] }
            ]
          }
        }
      }
    }
  },
  {
    $project: {
      id: 1,
      members: { $arrayToObject: "$members" }
    }
  }
])

Playground

Upvotes: 1

Related Questions