My mongoose schema has the following interface:
interface Voucher {
...
dateRedeemed?: Date;
merchant: string; // username of merchant
paymentStatus: 'paid' | 'unpaid';
...
}
By executing VoucherModel.aggregate
I want to return the result that has the following interface for a given merchant
:
{
totalPaid: number, //total count of where paymentStatus === 'paid'
totalUnpaid: number, //total count of where paymentStatus === 'unpaid'
totalRedeemed: Date, //total count of where dateRedeemed is defined
totalUnredeemed: Date, //total count of where dateRedeemed is undefined
}
CodePudding user response:
One option is to use $group
for this:
db.collection.aggregate([
{$match: {merchant: merchant, currency: currency}},
{$group: {
_id: 0,
totalPaid: {$sum: {$cond: [{$eq: ["$paymentStatus", "paid"]}, 1, 0]}},
totalUnredeemed: {$sum: {$ifNull: ["$dateRedeemed", 1, 0]}},
total: {$sum: 1}
}},
{$project: {
totalPaid: 1,
totalUnpaid: {$subtract: ["$total", "$totalPaid"]},
totalRedeemed: {$subtract: ["$total", "$totalUnredeemed"]},
totalUnredeemed: 1
}}
])
See how it works on the playground example