Home > database >  MongoDB get sum of fields which I have modified in the project pipeline
MongoDB get sum of fields which I have modified in the project pipeline

Time:04-28

I want to calculate netDueAmount as the sum 3 fields = [balanceLoaded operatorDueAmount - walletUsage]. But these fields can either be zero or themselves (balanceLoaded, operatorDueAmount, walletUsage) depending on the condition. I want to sum up the final value which is calculated after applying the condition. And yes I need to subtract the walletUsage from other fields. Can someone guide me on how to do that without changing the names of fields in the project pipeline?

const result = await BusDayWise.aggregate(
    [
        {
            $match: { ...filter },
        },
        {
            $project: {
                _id: 1,
                fromDate: '$fromDate',
                busNumber: '$busNumber',
                cardDueAmount: '$cardDueAmount',
                walletUsage: { $cond: [{ $in: ['digital', dueFieldsConfigs] }, '$walletUsage', 0] },
                balanceLoaded: { $cond: [{ $in: ['moneyLoaded', dueFieldsConfigs] }, '$balanceLoaded', 0] },
                operatorDueAmount: { $cond: [{ $in: ['contractual', dueFieldsConfigs] }, '$operatorPayout', 0] },
                netDueAmount: { $sum: ['$balanceLoaded', '$operatorDueAmount', '$walletUsage'] },
            },
        },
        { $sort: sort },
        { $skip: skip },
        { $limit: limit },
    ],
);

CodePudding user response:

You just can't reference the same field names as you're creating them, the easiest way would be to just add another stage after the initial $project stage:

const result = await BusDayWise.aggregate(
    [
        {
            $match: {...filter}
        },
        {
            $project: {
                _id: 1,
                fromDate: "$fromDate",
                busNumber: "$busNumber",
                cardDueAmount: "$cardDueAmount",
                walletUsage: { $cond: [ {$in: ["digital", dueFieldsConfigs] }, "$walletUsage", 0 ]},
                balanceLoaded: { $cond: [ { $in: ["moneyLoaded", dueFieldsConfigs] }, "$balanceLoaded", 0] },
                operatorDueAmount: { $cond: [ { $in: ["contractual", dueFieldsConfigs] }, "$operatorPayout", 0] },
            }
        },
        {
            $addFields: {
                netDueAmount: { $sum: ["$balanceLoaded", "$operatorDueAmount", "$walletUsage"] },
            }
        },
        { $sort: sort },
        { $skip: skip },
        { $limit: limit },
    ]
)

If for whatever reason you want to put it in the same stage you'll have to use the same condition to "calculate" them:

const result = await BusDayWise.aggregate(
    [
        {
            $match: { ...filter },
        },
        {
            $project: {
                _id: 1,
                fromDate: '$fromDate',
                busNumber: '$busNumber',
                cardDueAmount: '$cardDueAmount',
                walletUsage: { $cond: [{ $in: ['digital', dueFieldsConfigs] }, '$walletUsage', 0] },
                balanceLoaded: { $cond: [{ $in: ['moneyLoaded', dueFieldsConfigs] }, '$balanceLoaded', 0] },
                operatorDueAmount: { $cond: [{ $in: ['contractual', dueFieldsConfigs] }, '$operatorPayout', 0] },
                netDueAmount: {
                    $sum: [
                        { $cond: [{ $in: ['digital', dueFieldsConfigs] }, '$walletUsage', 0] },
                        { $cond: [{ $in: ['moneyLoaded', dueFieldsConfigs] }, '$balanceLoaded', 0] },
                        { $cond: [{ $in: ['contractual', dueFieldsConfigs] }, '$operatorPayout', 0] },
                    ],
                },
            },
        },
        { $sort: sort },
        { $skip: skip },
        { $limit: limit },
    ],
);
  • Related