Hello, @Erysson_Barros ! Welcome to the MongoDB community! ![]()
Since you veiled your collection structure and did not provide sample documents from your collections, I will make up my own simple test dataset:
db.employees.insertMany([
{
_id: 'E1',
name: 'Urko',
},
{
_id: 'E2',
name: 'Sashko',
},
{
_id: 'E3',
name: 'Ilko',
},
]);
db.workdays.insertMany([
{
date: ISODate('2023-08-21'),
employeeId: 'E1',
usdEarned: 380,
},
{
date: ISODate('2023-08-22'),
employeeId: 'E1',
usdEarned: 430,
},
{
date: ISODate('2023-08-21'),
employeeId: 'E2',
usdEarned: 450,
},
{
date: ISODate('2023-08-22'),
employeeId: 'E2',
usdEarned: 0,
},
]);
db.overtime.insertMany([
{
date: ISODate('2023-08-20'),
employeeId: 'E1',
usdEarned: 120,
},
]);
Solution 1 (with pipeline in $lookup)
// Solution 1 (with pipeline in $lookup)
db.employees.aggregate([
{
$lookup: {
from: 'workdays',
let: {
employeeId: '$_id',
},
pipeline: [
{
$match: {
$expr: {
$eq: ['$employeeId', '$$employeeId']
}
}
},
{
$group: {
_id: null,
total: {
$sum: '$usdEarned'
}
}
}
],
as: 'earnings'
}
},
{
$lookup: {
from: 'overtime',
let: {
employeeId: '$_id',
},
pipeline: [
{
$match: {
$expr: {
$eq: ['$employeeId', '$$employeeId']
}
}
},
{
$group: {
_id: null,
total: {
$sum: '$usdEarned'
}
}
}
],
as: 'overtime'
}
},
{
$unwind: {
path: '$earnings',
preserveNullAndEmptyArrays: true,
}
},
{
$unwind: {
path: '$overtime',
preserveNullAndEmptyArrays: true,
}
},
{
$project: {
name: '$name',
totalUsdEarned: {
$sum: ['$earnings.total', '$overtime.total']
}
}
}
]);
Solution 2: With sequential $lookup + $group + $unwind stages
// Solution 2: With sequential $lookup + $group + $unwind stages
db.employees.aggregate([
{
$lookup: {
from: 'workdays',
localField: '_id',
foreignField: 'employeeId',
as: 'earnings'
}
},
{
$unwind: {
path: '$earnings',
preserveNullAndEmptyArrays: true,
}
},
{
$group: {
_id: {
_id: '$_id',
name: '$name',
},
totalUsdEarned: {
$sum: '$earnings.usdEarned'
}
}
},
{
$lookup: {
from: 'overtime',
localField: '_id._id',
foreignField: 'employeeId',
as: 'overtime'
}
},
{
$unwind: {
path: '$overtime',
preserveNullAndEmptyArrays: true,
}
},
{
$group: {
_id: {
name: '$_id.name',
totalUsdEarned: '$totalUsdEarned',
},
totalUsdFromOvertime: {
$sum: '$overtime.usdEarned'
}
}
},
{
$project: {
_id: false,
name: '$_id.name',
totalUsdEarned: {
$sum: ['$_id.totalUsdEarned','$totalUsdFromOvertime']
}
}
}
]);
Output is the same for both aggregations:
[
{ name: 'Urko', totalEarned: 810 },
{ name: 'Ilko', totalEarned: 0 },
{ name: 'Sashko', totalEarned: 450 }
]
Feel free to adapt before usage any of those approaches whichever you feel is more convenient or efficient in your specific use case ![]()