2020-10-05 09:16:21 +00:00
|
|
|
import mongodb from '@ioc:Mongodb/Database'
|
2020-10-05 17:49:03 +00:00
|
|
|
import { Collection } from 'mongodb'
|
2020-10-05 09:16:21 +00:00
|
|
|
|
|
|
|
|
class MatchRepository {
|
2020-10-05 17:49:03 +00:00
|
|
|
private collection: Collection
|
2020-10-05 09:16:21 +00:00
|
|
|
|
|
|
|
|
constructor () {
|
2020-10-05 17:49:03 +00:00
|
|
|
this.getCollection()
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-05 09:16:21 +00:00
|
|
|
/**
|
|
|
|
|
* Basic matchParams used in a lot of requests
|
|
|
|
|
* @param puuid of the summoner
|
|
|
|
|
*/
|
2020-10-05 19:33:17 +00:00
|
|
|
private matchParams (puuid: string, season?: number) {
|
2020-10-05 09:16:21 +00:00
|
|
|
return {
|
|
|
|
|
summoner_puuid: puuid,
|
|
|
|
|
result: { $not: { $eq: 'Remake' } },
|
|
|
|
|
gamemode: { $nin: [800, 810, 820, 830, 840, 850] },
|
2020-10-05 19:33:17 +00:00
|
|
|
season: season ? season : { $exists: true },
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Build the aggregate mongo query
|
|
|
|
|
* @param puuid
|
|
|
|
|
* @param matchParams
|
|
|
|
|
* @param intermediateSteps
|
|
|
|
|
* @param groupId
|
|
|
|
|
* @param groupParams
|
|
|
|
|
* @param finalSteps
|
|
|
|
|
*/
|
|
|
|
|
private async aggregate (
|
|
|
|
|
puuid: string,
|
|
|
|
|
matchParams: object,
|
|
|
|
|
intermediateSteps: any[],
|
|
|
|
|
groupId: any,
|
|
|
|
|
groupParams: object,
|
|
|
|
|
finalSteps: any[],
|
|
|
|
|
season?: number,
|
|
|
|
|
) {
|
|
|
|
|
return this.collection.aggregate([
|
|
|
|
|
{
|
|
|
|
|
$match: {
|
|
|
|
|
...this.matchParams(puuid, season),
|
|
|
|
|
...matchParams,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
...intermediateSteps,
|
|
|
|
|
{
|
|
|
|
|
$group: {
|
|
|
|
|
_id: groupId,
|
|
|
|
|
count: { $sum: 1 },
|
|
|
|
|
wins: {
|
|
|
|
|
$sum: {
|
|
|
|
|
$cond: [{ $eq: ['$result', 'Win'] }, 1, 0],
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
losses: {
|
|
|
|
|
$sum: {
|
|
|
|
|
$cond: [{ $eq: ['$result', 'Fail'] }, 1, 0],
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
...groupParams,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
...finalSteps,
|
|
|
|
|
]).toArray()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get MongoDB matches collection
|
|
|
|
|
*/
|
|
|
|
|
public async getCollection () {
|
|
|
|
|
if (!this.collection) {
|
|
|
|
|
this.collection = await mongodb.connection().collection('matches')
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-08 07:51:12 +00:00
|
|
|
/**
|
|
|
|
|
* Get Summoner's statistics for the N most played champions
|
|
|
|
|
* @param puuid of the summoner
|
|
|
|
|
* @param limit number of champions to fetch
|
|
|
|
|
* @param season
|
|
|
|
|
*/
|
|
|
|
|
public async championStats (puuid: string, limit = 5, season?: number) {
|
|
|
|
|
const groupParams = {
|
|
|
|
|
champion: { $first: '$champion' },
|
|
|
|
|
kills: { $sum: '$stats.kills' },
|
|
|
|
|
deaths: { $sum: '$stats.deaths' },
|
|
|
|
|
assists: { $sum: '$stats.assists' },
|
|
|
|
|
}
|
|
|
|
|
const finalSteps = [
|
|
|
|
|
{ $sort: { 'count': -1, 'champion.name': 1 } },
|
|
|
|
|
{ $limit: limit },
|
|
|
|
|
]
|
|
|
|
|
return this.aggregate(puuid, {}, [], '$champion.id', groupParams, finalSteps, season)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get Summoner's statistics for all played champion classes
|
|
|
|
|
* @param puuid of the summoner
|
|
|
|
|
* @param season
|
|
|
|
|
*/
|
|
|
|
|
public async championClassStats (puuid: string, season?: number) {
|
|
|
|
|
const groupId = { '$arrayElemAt': ['$champion.roles', 0] }
|
|
|
|
|
return this.aggregate(puuid, {}, [], groupId, {}, [], season)
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-05 19:33:17 +00:00
|
|
|
/**
|
|
|
|
|
* Get Summoner's complete statistics for the all played champs
|
|
|
|
|
* @param puuid of the summoner
|
|
|
|
|
* @param queue of the matches to fetch, if not set: get all matches
|
|
|
|
|
* @param season of the matches to fetch, if not set: get all seasons
|
|
|
|
|
*/
|
|
|
|
|
public async championCompleteStats (puuid: string, queue?: number, season?: number) {
|
|
|
|
|
const matchParams = queue ? { gamemode: { $eq: Number(queue) } } : {}
|
|
|
|
|
const groupParams = {
|
|
|
|
|
time: { $sum: '$time' },
|
|
|
|
|
gameLength: { $avg: '$time' },
|
|
|
|
|
date: { $max: '$date' },
|
|
|
|
|
champion: { $first: '$champion' },
|
|
|
|
|
kills: { $sum: '$stats.kills' },
|
|
|
|
|
deaths: { $sum: '$stats.deaths' },
|
|
|
|
|
assists: { $sum: '$stats.assists' },
|
|
|
|
|
minions: { $avg: '$stats.minions' },
|
|
|
|
|
gold: { $avg: '$stats.gold' },
|
|
|
|
|
dmgChamp: { $avg: '$stats.dmgChamp' },
|
|
|
|
|
dmgTaken: { $avg: '$stats.dmgTaken' },
|
|
|
|
|
kp: { $avg: '$stats.kp' },
|
2020-10-05 09:16:21 +00:00
|
|
|
}
|
2020-10-05 19:33:17 +00:00
|
|
|
const finalSteps = [
|
|
|
|
|
{ $sort: { 'count': -1, 'champion.name': 1 } },
|
|
|
|
|
]
|
|
|
|
|
return this.aggregate(puuid, matchParams, [], '$champion.id', groupParams, finalSteps, season)
|
2020-10-05 09:16:21 +00:00
|
|
|
}
|
2020-10-05 17:49:03 +00:00
|
|
|
|
2020-10-08 07:51:12 +00:00
|
|
|
/**
|
|
|
|
|
* Get Summoner's statistics for all played modes
|
|
|
|
|
* @param puuid of the summoner
|
|
|
|
|
* @param season
|
|
|
|
|
*/
|
|
|
|
|
public async gamemodeStats (puuid: string, season?: number) {
|
|
|
|
|
return this.aggregate(puuid, {}, [], '$gamemode', {}, [], season)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get global Summoner's statistics
|
|
|
|
|
* @param puuid of the summoner
|
|
|
|
|
* @param season
|
|
|
|
|
*/
|
|
|
|
|
public async globalStats (puuid: string, season?: number) {
|
|
|
|
|
const groupParams = {
|
|
|
|
|
time: { $sum: '$time' },
|
|
|
|
|
kills: { $sum: '$stats.kills' },
|
|
|
|
|
deaths: { $sum: '$stats.deaths' },
|
|
|
|
|
assists: { $sum: '$stats.assists' },
|
|
|
|
|
minions: { $sum: '$stats.minions' },
|
|
|
|
|
vision: { $sum: '$stats.vision' },
|
|
|
|
|
kp: { $avg: '$stats.kp' },
|
|
|
|
|
}
|
|
|
|
|
return this.aggregate(puuid, {}, [], null, groupParams, [], season)
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-07 15:47:27 +00:00
|
|
|
/**
|
|
|
|
|
* Get Summoner's all records
|
|
|
|
|
* @param puuid of the summoner
|
|
|
|
|
* @param season of the matches to fetch, if null get all seasons
|
|
|
|
|
*/
|
|
|
|
|
public async records (puuid: string, season?: number) {
|
|
|
|
|
const records = await this.collection.aggregate([
|
|
|
|
|
{
|
|
|
|
|
$match: {
|
|
|
|
|
...this.matchParams(puuid, season),
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
$group: {
|
|
|
|
|
_id: null,
|
|
|
|
|
maxKills: { $max: '$stats.kills' },
|
|
|
|
|
maxDeaths: { $max: '$stats.deaths' },
|
|
|
|
|
maxAssists: { $max: '$stats.assists' },
|
|
|
|
|
maxGold: { $max: '$stats.gold' },
|
|
|
|
|
maxTime: { $max: '$time' },
|
|
|
|
|
maxMinions: { $max: '$stats.minions' },
|
|
|
|
|
maxKda: { $max: '$stats.realKda' },
|
|
|
|
|
maxDmgTaken: { $max: '$stats.dmgTaken' },
|
|
|
|
|
maxDmgChamp: { $max: '$stats.dmgChamp' },
|
|
|
|
|
maxDmgObj: { $max: '$stats.dmgObj' },
|
|
|
|
|
maxKp: { $max: '$stats.kp' },
|
|
|
|
|
maxVision: { $max: '$stats.vision' },
|
|
|
|
|
maxCriticalStrike: { $max: '$stats.criticalStrike' },
|
|
|
|
|
maxLiving: { $max: '$stats.longestLiving' },
|
|
|
|
|
maxHeal: { $max: '$stats.heal' },
|
|
|
|
|
maxTowers: { $max: '$stats.towers' },
|
|
|
|
|
maxKillingSpree: { $max: '$stats.killingSpree' },
|
|
|
|
|
maxDouble: { $max: '$stats.doubleKills' },
|
|
|
|
|
maxTriple: { $max: '$stats.tripleKills' },
|
|
|
|
|
maxQuadra: { $max: '$stats.quadraKills' },
|
|
|
|
|
maxPenta: { $max: '$stats.pentaKills' },
|
|
|
|
|
docs: {
|
|
|
|
|
'$push': {
|
|
|
|
|
'champion': '$champion',
|
|
|
|
|
'gameId': '$gameId',
|
|
|
|
|
'kills': '$stats.kills',
|
|
|
|
|
'deaths': '$stats.deaths',
|
|
|
|
|
'assists': '$stats.assists',
|
|
|
|
|
'gold': '$stats.gold',
|
|
|
|
|
'time': '$time',
|
|
|
|
|
'minions': '$stats.minions',
|
|
|
|
|
'kda': '$stats.realKda',
|
|
|
|
|
'dmgTaken': '$stats.dmgTaken',
|
|
|
|
|
'dmgChamp': '$stats.dmgChamp',
|
|
|
|
|
'dmgObj': '$stats.dmgObj',
|
|
|
|
|
'kp': '$stats.kp',
|
|
|
|
|
'vision': '$stats.vision',
|
|
|
|
|
'criticalStrike': '$stats.criticalStrike',
|
|
|
|
|
'longestLiving': '$stats.longestLiving',
|
|
|
|
|
'heal': '$stats.heal',
|
|
|
|
|
'towers': '$stats.towers',
|
|
|
|
|
'killingSpree': '$stats.killingSpree',
|
|
|
|
|
'doubleKills': '$stats.doubleKills',
|
|
|
|
|
'tripleKills': '$stats.tripleKills',
|
|
|
|
|
'quadraKills': '$stats.quadraKills',
|
|
|
|
|
'pentaKills': '$stats.pentaKills',
|
|
|
|
|
'result': '$result',
|
|
|
|
|
'date': '$date',
|
|
|
|
|
'gamemode': '$gamemode',
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
$project: {
|
|
|
|
|
_id: 0,
|
|
|
|
|
/* eslint-disable max-len */
|
|
|
|
|
maxKills: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.kills', '$maxKills'] } } }, 0] },
|
|
|
|
|
maxDeaths: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.deaths', '$maxDeaths'] } } }, 0] },
|
|
|
|
|
maxAssists: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.assists', '$maxAssists'] } } }, 0] },
|
|
|
|
|
maxGold: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.gold', '$maxGold'] } } }, 0] },
|
|
|
|
|
maxTime: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.time', '$maxTime'] } } }, 0] },
|
|
|
|
|
maxMinions: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.minions', '$maxMinions'] } } }, 0] },
|
|
|
|
|
maxKda: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.kda', '$maxKda'] } } }, 0] },
|
|
|
|
|
maxDmgTaken: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.dmgTaken', '$maxDmgTaken'] } } }, 0] },
|
|
|
|
|
maxDmgChamp: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.dmgChamp', '$maxDmgChamp'] } } }, 0] },
|
|
|
|
|
maxDmgObj: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.dmgObj', '$maxDmgObj'] } } }, 0] },
|
|
|
|
|
maxKp: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.kp', '$maxKp'] } } }, 0] },
|
|
|
|
|
maxVision: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.vision', '$maxVision'] } } }, 0] },
|
|
|
|
|
maxCriticalStrike: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.criticalStrike', '$maxCriticalStrike'] } } }, 0] },
|
|
|
|
|
maxLiving: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.longestLiving', '$maxLiving'] } } }, 0] },
|
|
|
|
|
maxHeal: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.heal', '$maxHeal'] } } }, 0] },
|
|
|
|
|
maxTowers: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.towers', '$maxTowers'] } } }, 0] },
|
|
|
|
|
maxKillingSpree: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.killingSpree', '$maxKillingSpree'] } } }, 0] },
|
|
|
|
|
maxDouble: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.doubleKills', '$maxDouble'] } } }, 0] },
|
|
|
|
|
maxTriple: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.tripleKills', '$maxTriple'] } } }, 0] },
|
|
|
|
|
maxQuadra: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.quadraKills', '$maxQuadra'] } } }, 0] },
|
|
|
|
|
maxPenta: { $arrayElemAt: [{ $filter: { input: '$docs', cond: { $eq: ['$$this.pentaKills', '$maxPenta'] } } }, 0] },
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
]).toArray()
|
|
|
|
|
|
|
|
|
|
return records[0]
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-08 07:51:12 +00:00
|
|
|
/**
|
|
|
|
|
* Get Summoner's statistics for the 5 differnt roles
|
|
|
|
|
* @param puuid of the summoner
|
|
|
|
|
* @param season
|
|
|
|
|
*/
|
|
|
|
|
public async roleStats (puuid: string, season?: number) {
|
|
|
|
|
const matchParams = {
|
|
|
|
|
role: { $not: { $eq: 'NONE' } },
|
|
|
|
|
}
|
|
|
|
|
const finalSteps = [
|
|
|
|
|
{
|
|
|
|
|
$project: {
|
|
|
|
|
role: '$_id',
|
|
|
|
|
count: '$count',
|
|
|
|
|
wins: '$wins',
|
|
|
|
|
losses: '$losses',
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
]
|
|
|
|
|
return this.aggregate(puuid, matchParams, [], '$role', {}, finalSteps, season)
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-05 09:16:21 +00:00
|
|
|
/**
|
|
|
|
|
* Get Summoner's played seasons
|
|
|
|
|
* @param puuid of the summoner
|
|
|
|
|
*/
|
|
|
|
|
public async seasons (puuid: string) {
|
2020-10-05 17:49:03 +00:00
|
|
|
return this.collection.aggregate([
|
2020-10-05 09:16:21 +00:00
|
|
|
{
|
|
|
|
|
$match: {
|
2020-10-05 17:49:03 +00:00
|
|
|
...this.matchParams(puuid),
|
2020-10-05 09:16:21 +00:00
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
$group: { _id: '$season' },
|
|
|
|
|
},
|
|
|
|
|
]).toArray()
|
|
|
|
|
}
|
2020-10-08 07:51:12 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get Summoner's mates list
|
|
|
|
|
* @param puuid of the summoner
|
|
|
|
|
* @param season
|
|
|
|
|
*/
|
|
|
|
|
public async mates (puuid: string, season?: number) {
|
|
|
|
|
const intermediateSteps = [
|
|
|
|
|
{ $sort: { 'gameId': -1 } },
|
|
|
|
|
{ $unwind: '$allyTeam' },
|
|
|
|
|
]
|
|
|
|
|
const groupParams = {
|
|
|
|
|
account_id: { $first: '$account_id' },
|
|
|
|
|
name: { $first: '$allyTeam.name' },
|
|
|
|
|
mateId: { $first: '$allyTeam.account_id' },
|
|
|
|
|
}
|
|
|
|
|
const finalSteps = [
|
|
|
|
|
{
|
|
|
|
|
'$addFields': {
|
|
|
|
|
'idEq': { '$eq': ['$mateId', '$account_id'] },
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
$match: {
|
|
|
|
|
'idEq': false,
|
|
|
|
|
'count': { $gte: 2 },
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{ $sort: { 'count': -1, 'name': 1 } },
|
|
|
|
|
{ $limit: 15 },
|
|
|
|
|
]
|
|
|
|
|
return this.aggregate(puuid, {}, intermediateSteps, '$allyTeam.account_id', groupParams, finalSteps, season)
|
|
|
|
|
}
|
2020-10-05 09:16:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default new MatchRepository()
|