Wednesday 17 May 2017

How can I make a very large MongoDB query into one but keep it structured

I currently run https://playersareknown.net and if you scroll down, you'll see the top leaderboards for different regions, you'll also see it probably takes a few seconds to populate, that would probably be because of this very large database search in this function:

Stats.prototype.getTopPlayers = function() {
    return new Promise(async (resolve, reject) => {
        try {
            let topSoloStatsNA = this.col.find({ 
                [monthName + '.na.solo.records.Rating'] : { $ne: 0, $exists: true },
                [monthName + 'Elo']: { $exists: true },
                [monthName + 'Elo.na.solo']: { $ne: 0 }
            }).sort({ [monthName + '.na.solo.records']: -1  }).limit(5).toArrayAsync();
            let topSoloStatsEU = this.col.find({ 
                [monthName + '.eu.solo.records.Rating'] : { $ne: 0, $exists: true },
                [monthName + 'Elo']: { $exists: true },
                [monthName + 'Elo.eu.solo']: { $ne: 0 }
            }).sort({ [monthName + '.eu.solo.records']: -1  }).limit(5).toArrayAsync();
            let topSoloStatsAS = this.col.find({ 
                [monthName + '.as.solo.records.Rating'] : { $ne: 0, $exists: true },
                [monthName + 'Elo']: { $exists: true },
                [monthName + 'Elo.as.solo']: { $ne: 0 }
            }).sort({ [monthName + '.as.solo.records']: -1  }).limit(5).toArrayAsync();
            let topSoloStatsSA = this.col.find({ 
                [monthName + '.sa.solo.records.Rating'] : { $ne: 0, $exists: true },
                [monthName + 'Elo']: { $exists: true },
                [monthName + 'Elo.sa.solo']: { $ne: 0 }
            }).sort({ [monthName + '.as.solo.records']: -1  }).limit(5).toArrayAsync();
            let topSoloStatsOC = this.col.find({ 
                [monthName + '.oc.solo.records.Rating'] : { $ne: 0, $exists: true },
                [monthName + 'Elo']: { $exists: true },
                [monthName + 'Elo.oc.solo']: { $ne: 0 }
            }).sort({ [monthName + '.as.solo.records']: -1  }).limit(5).toArrayAsync();

            let topDuoStatsNA = this.col.find({ 
                [monthName + '.na.duo.records.Rating'] : { $ne: 0, $exists: true },
                [monthName + 'Elo']: { $exists: true },
                [monthName + 'Elo.na.solo']: { $ne: 0 }
            }).sort({ [monthName + '.na.solo.records']: -1  }).limit(5).toArrayAsync();
            let topDuoStatsEU = this.col.find({ 
                [monthName + '.eu.duo.records.Rating'] : { $ne: 0, $exists: true },
                [monthName + 'Elo']: { $exists: true },
                [monthName + 'Elo.eu.solo']: { $ne: 0 }
            }).sort({ [monthName + '.eu.solo.records']: -1  }).limit(5).toArrayAsync();
            let topDuoStatsAS = this.col.find({ 
                [monthName + '.as.duo.records.Rating'] : { $ne: 0, $exists: true },
                [monthName + 'Elo']: { $exists: true },
                [monthName + 'Elo.as.solo']: { $ne: 0 }
            }).sort({ [monthName + '.as.solo.records']: -1  }).limit(5).toArrayAsync();
            let topDuoStatsSA = this.col.find({ 
                [monthName + '.sa.duo.records.Rating'] : { $ne: 0, $exists: true },
                [monthName + 'Elo']: { $exists: true },
                [monthName + 'Elo.sa.solo']: { $ne: 0 }
            }).sort({ [monthName + '.as.solo.records']: -1  }).limit(5).toArrayAsync();
            let topDuoStatsOC = this.col.find({ 
                [monthName + '.oc.duo.records.Rating'] : { $ne: 0, $exists: true },
                [monthName + 'Elo']: { $exists: true },
                [monthName + 'Elo.oc.solo']: { $ne: 0 }
            }).sort({ [monthName + '.as.solo.records']: -1  }).limit(5).toArrayAsync();

            let topSquadStatsNA = this.col.find({ 
                [monthName + '.na.squad.records.Rating'] : { $ne: 0, $exists: true },
                [monthName + 'Elo']: { $exists: true },
                [monthName + 'Elo.na.solo']: { $ne: 0 }
            }).sort({ [monthName + '.na.solo.records']: -1  }).limit(5).toArrayAsync();
            let topSquadStatsEU = this.col.find({ 
                [monthName + '.eu.squad.records.Rating'] : { $ne: 0, $exists: true },
                [monthName + 'Elo']: { $exists: true },
                [monthName + 'Elo.eu.solo']: { $ne: 0 }
            }).sort({ [monthName + '.eu.solo.records']: -1  }).limit(5).toArrayAsync();
            let topSquadStatsAS = this.col.find({ 
                [monthName + '.as.squad.records.Rating'] : { $ne: 0, $exists: true },
                [monthName + 'Elo']: { $exists: true },
                [monthName + 'Elo.as.solo']: { $ne: 0 }
            }).sort({ [monthName + '.as.solo.records']: -1  }).limit(5).toArrayAsync();
            let topSquadStatsSA = this.col.find({ 
                [monthName + '.sa.squad.records.Rating'] : { $ne: 0, $exists: true },
                [monthName + 'Elo']: { $exists: true },
                [monthName + 'Elo.sa.solo']: { $ne: 0 }
            }).sort({ [monthName + '.as.solo.records']: -1  }).limit(5).toArrayAsync();
            let topSquadStatsOC = this.col.find({ 
                [monthName + '.oc.squad.records.Rating'] : { $ne: 0, $exists: true },
                [monthName + 'Elo']: { $exists: true },
                [monthName + 'Elo.oc.solo']: { $ne: 0 }
            }).sort({ [monthName + '.as.solo.records']: -1  }).limit(5).toArrayAsync();

            let promiseArray = [
                topSoloStatsNA,
                topSoloStatsEU,
                topSoloStatsOC,
                topSoloStatsSA,
                topSoloStatsAS,
                topDuoStatsNA,
                topDuoStatsEU,
                topDuoStatsOC,
                topDuoStatsSA,
                topDuoStatsAS,
                topSquadStatsNA,
                topSquadStatsEU,
                topSquadStatsOC,
                topSquadStatsSA,
                topSquadStatsAS,
            ]

            let [
                soloStatsNA,
                soloStatsEU,
                soloStatsOC,
                soloStatsSA,
                soloStatsAS,
                duoStatsNA,
                duoStatsEU,
                duoStatsOC,
                duoStatsSA,
                duoStatsAS,
                squadStatsNA,
                squadStatsEU,
                squadStatsOC,
                squadStatsSA,
                squadStatsAS,
            ] = await Promise.all(promiseArray);

            return resolve([
                soloStatsNA,
                soloStatsEU,
                soloStatsOC,
                soloStatsSA,
                soloStatsAS,
                duoStatsNA,
                duoStatsEU,
                duoStatsOC,
                duoStatsSA,
                duoStatsAS,
                squadStatsNA,
                squadStatsEU,
                squadStatsOC,
                squadStatsSA,
                squadStatsAS
            ]);


        } catch(err) {
            console.log(err);
        }
    });
}

I was wondering how I might streamline this into 1 massive query, but keeping the structure so I know what belongs to what region / match type which is why I have each query into each array so I know what result is what.

Anyways I was wondering how I might refactor this function to return the same result with much more speed.



via Datsik

No comments:

Post a Comment