Dividing an element from one array by an element in a different array in mongodb aggregation

31 views Asked by At

Here's my current code:

const mostPlayedCards = async (cardType, colorIdentity) => {
    const coloridentity = await decksByGlobalColorIdentity();

    const totalDecks = await Deck.aggregate([
        {
            $count: 'count',
        },
    ]);

    const pipeline = [
        {
            $project: {
                cards: {
                    $objectToArray: '$Decklist',
                },
            },
        },
        {
            $unwind: '$cards',
        },
    ];

    if (cardType) {
        pipeline.push({
            $match: {
                'cards.v.card.type_line': new RegExp(`^${cardType}$`, 'i'),
            },
        });
    }

    if (colorIdentity && colorIdentity.length > 0) {
        pipeline.push({
            $match: {
                'cards.v.card.color_identity': { $all: colorIdentity },
            },
        });
    }

    pipeline.push(
        {
            $group: {
                _id: {
                    card: '$cards.k',
                    color: '$cards.v.card.color_identity',
                    cardType: '$cards.v.card.type_line',
                },
                count: {
                    $sum: 1,
                },
            },
        },
        {
            $project: {
                _id: 0,
                'Card Name': '$_id.card',
                'Color Identity': '$_id.color',
                'Card Type': '$_id.cardType',
                'In Number of Decks': '$count',
                // Calculating the percentage of decks with the same color identity
                percentageOfDecks: {
                    $multiply: [{ $divide: ['$count', totalDecks[0].count] }, 100],
                },

                percentageOfColoredDecks: {
                    $let: {
                        vars: {
                            colorCount: {
                                $cond: {
                                    if: { $eq: ['$_id.color', []] },
                                    then: totalDecks[0].count,
                                    else: {
                                        $arrayElemAt: [
                                            {
                                                $filter: {
                                                    input: '$coloridentity',
                                                    cond: { $eq: ['$_id.color', '$$this._id'] },
                                                },
                                            },
                                            0,
                                        ],
                                    },
                                },
                            },
                        },
                        in: {
                            $multiply: [{ $divide: ['$count', '$$colorCount.count'] }, 100],
                        },
                    },
                },
            },
        },
        {
            $project: {
                'Card Name': 1,
                'Color Identity': 1,
                'Card Type': 1,
                'In Number of Decks': 1,
                // Calculating the percentage of decks
                '% of Decks': {
                    $round: ['$percentageOfDecks', 2],
                },
                // Calculating the percentage of decks with the same color identity
                '% of Decks in Color': {
                    $round: ['$percentageOfDecks', 2],
                },
            },
        },
        {
            $sort: {
                'In Number of Decks': -1,
            },
        }
    );
    console.log(totalDecks, coloridentity);
    // Run the aggregation pipeline
    const results = await Deck.aggregate(pipeline);
    console.log(cardType, colorIdentity);
    return results;
};

coloridentity will give us the following array:

[
    {
        "_id": "W",
        "count": 113
    },
    {
        "_id": "U",
        "count": 150
    },
    {
        "_id": "B",
        "count": 146
    },
    {
        "_id": "R",
        "count": 124
    },
    {
        "_id": "G",
        "count": 136
    },
    {
        "_id": "WU",
        "count": 65
    },
    {
        "_id": "WB",
        "count": 69
    },
    {
        "_id": "WR",
        "count": 56
    },
    {
        "_id": "WG",
        "count": 75
    },
    {
        "_id": "UB",
        "count": 97
    },
    {
        "_id": "UR",
        "count": 80
    },
    {
        "_id": "UG",
        "count": 82
    },
    {
        "_id": "BR",
        "count": 74
    },
    {
        "_id": "BG",
        "count": 86
    },
    {
        "_id": "RG",
        "count": 66
    },
    {
        "_id": "WUB",
        "count": 46
    },
    {
        "_id": "WUR",
        "count": 32
    },
    {
        "_id": "WUG",
        "count": 41
    },
    {
        "_id": "WBR",
        "count": 33
    },
    {
        "_id": "WBG",
        "count": 47
    },
    {
        "_id": "WRG",
        "count": 41
    },
    {
        "_id": "UBR",
        "count": 50
    },
    {
        "_id": "UBG",
        "count": 52
    },
    {
        "_id": "URG",
        "count": 41
    },
    {
        "_id": "BRG",
        "count": 40
    },
    {
        "_id": "WUBR",
        "count": 22
    },
    {
        "_id": "WUBG",
        "count": 28
    },
    {
        "_id": "WURG",
        "count": 24
    },
    {
        "_id": "WBRG",
        "count": 26
    },
    {
        "_id": "UBRG",
        "count": 26
    },
    {
        "_id": "WUBRG",
        "count": 18
    }
]

What i'm currently looking for is the code in "percentageOfColoredDecks" - and figure out how to divide the color identity of the current card that i'm looking at by it's corresponding color identity in the coloridentity array that i've received. However i'm not really sure what to do and chatGPT where I got the current code isn't being really helpful about this...

So for example, let's say the cards color identity is [ "B" ], I want it to check the number of times that it appears (count) and divide that by the number in coloridentity wherein _id = "B". So it should be:

count X 146 / 100

If the cards color identity is [ "W", "B"] then it should look for "WB" in coloridentity and divide it by that number or

count x 69 / 100

Hope that makes it clear. I'll be happy to explain more if need be!

0

There are 0 answers