Database

[{_winnerId:"userA",_loserId:"userB",},{_winnerId:"userA",_loserId:"userC"},{_winnerId:"userA",_loserId:"userC"},{_winnerId:"userA",_loserId:"userZ"},{_winnerId:"userC",_loserId:"userZ"}]

Query

db.collection.aggregate([/** Combine the user _ids*/{$group:{_id:["$_loserId","$_winnerId"],/** Track the amount of times user X lost to user Y*/times:{$sum:1}}},/** Seperate the user _ids*//** Track whether the user won by setting field 'lostWon': 0 if they lost 1 if they won*/{$unwind:{path:"$_id",includeArrayIndex:"lostWon"}},/** Create a group for each user _id, user the 'lostWon' field to sum the totals*/{$group:{_id:"$_id",lost:{$sum:{$multiply:["$times",{$cond:[{$eq:["$lostWon",0]},1,0]}/** Important: swaps the values*/]}},won:{$sum:{$multiply:["$times",{$cond:[{$eq:["$lostWon",1]},1,0]}/** This line is reduntant, but make query more understandable*/]}},}},/** Divide the ratio, if $lost is 0 use the won field value to avoid infinity*/{$addFields:{ratio:{$cond:[{$eq:["$lost",0]},"$won",{$divide:["$won","$lost"]}]}}}])

Result