How to aggregate collection sub-array objects with their actual object which is present in the other collection?
Ex: This is how my collections look like
Collection 1 – (Teams)
const Teams = [
{
_id: '60f3b0b3f0b9a1b0b4f9b1a1',
teamName: 'World XI A',
totalPlayers: 15,
player: [
{
playerId: '60f3b0b3f0b9a1b0b4f9b1a2',
playerName: 'Player A',
score: 10,
},
{
playerId: '60f3b0b3f0b9a1b0b4f9b1a3',
playerName: 'Player B',
score: 20,
},
],
},
{
_id: '60f3b0b3f0b9a1b0b4f9b1a4',
teamName: 'Crackers',
totalPlayers: 15,
player: [
{
playerId: '60f3b0b3f0b9a1b0b4f9b1a5',
playerName: 'Player C',
score: 30,
},
{
playerId: '60f3b0b3f0b9a1b0b4f9b1a6',
playerName: 'Player D',
score: 40,
},
],
},
];
Collection 2 – (Players)
const Players = [
{
_id: '60f3b0b3f0b9a1b0b4f9b1a2',
playerName: 'Player A',
rank: 2,
totalRuns: 5000,
},
{
_id: '60f3b0b3f0b9a1b0b4f9b1a3',
playerName: 'Player B',
rank: 1,
totalRuns: 3050,
},
{
_id: '60f3b0b3f0b9a1b0b4f9b1a5',
playerName: 'Player C',
rank: 3,
totalRuns: 2050,
},
{
_id: '60f3b0b3f0b9a1b0b4f9b1a6',
playerName: 'Player D',
rank: 4,
totalRuns: 1000,
},
];
Result: This is how the resultant array should look like
Resultant array
const result = [
{
_id: '60f3b0b3f0b9a1b0b4f9b1a1',
teamName: 'World XI A',
totalPlayers: 15,
player: [
{
playerInfo: {
_id: '60f3b0b3f0b9a1b0b4f9b1a2',
playerName: 'Player A',
rank: 2,
totalRuns: 5000,
},
playerName: 'Player A',
score: 10,
},
{
playerInfo: {
_id: '60f3b0b3f0b9a1b0b4f9b1a3',
playerName: 'Player B',
rank: 1,
totalRuns: 3050,
},
playerName: 'Player B',
score: 20,
},
],
},
{
_id: '60f3b0b3f0b9a1b0b4f9b1a4',
teamName: 'Crackers',
totalPlayers: 15,
player: [
{
playerInfo: {
_id: '60f3b0b3f0b9a1b0b4f9b1a5',
playerName: 'Player C',
rank: 3,
totalRuns: 2050,
},
playerName: 'Player C',
score: 30,
},
{
playerInfo: {
_id: '60f3b0b3f0b9a1b0b4f9b1a6',
playerName: 'Player D',
rank: 4,
totalRuns: 1000,
},
playerName: 'Player D',
score: 40,
},
],
},
];
2
Answers
$lookup
– Join both Teams and Players collections with fields. And return theplayers
array field.$set
– Set theplayer
field.2.1.
$map
– Iterate element in theplayer
array and return a new array.2.1.1.
$mergeObjects
– Merge the current iterated document with the document with theplayerInfo
field from the result 2.1.1.1.2.1.1.1.
$first
– Get the first matching document from the result 2.1.1.1.1.2.1.1.1.1.
$filter
– Filter the document in theplayers
array that matches the_id
.$unset
– Remove the fields:players
field andplayer.playerId
fields.Demo @ Mongo Playground
This is really just a case of a nested map over the
Player
array within each team in theTeams
array and adding the matching element from thePlayers
array by id. Here creating aMap
of players by id first for efficient access.