diff --git a/apps/api/src/player/player.service.ts b/apps/api/src/player/player.service.ts index 6bc9d8953..91059f65c 100644 --- a/apps/api/src/player/player.service.ts +++ b/apps/api/src/player/player.service.ts @@ -11,6 +11,7 @@ import { type Circular, type Flatten, flatten, + unflatten, } from "@statsify/util"; import { CacheLevel, StatusNotFoundException } from "@statsify/api-client"; import { HypixelService } from "#hypixel"; @@ -176,8 +177,11 @@ export class PlayerService { const serializedPlayer = serialize(Player, flatPlayer); const promises = [ + // Thousands of dotted keys make Mongoose's change tracking O(n²) this.playerModel - .replaceOne({ uuid: player.uuid }, serializedPlayer, { upsert: true }) + .replaceOne({ uuid: player.uuid }, unflatten(serializedPlayer), { + upsert: true, + }) .exec(), this.playerLeaderboardService.addLeaderboards( Player, diff --git a/apps/api/src/session/session.service.ts b/apps/api/src/session/session.service.ts index 0675b3826..2c38c93ba 100644 --- a/apps/api/src/session/session.service.ts +++ b/apps/api/src/session/session.service.ts @@ -11,7 +11,7 @@ import { PlayerNotFoundException, SessionNotFoundException, } from "@statsify/api-client"; -import { type Circular, flatten } from "@statsify/util"; +import { type Circular, flatten, unflatten } from "@statsify/util"; import { DateTime } from "luxon"; import { Inject, @@ -59,7 +59,7 @@ export class SessionService { const doc = serialize(Player, flatPlayer); - await this.sessionModel.replaceOne({ uuid: doc.uuid }, doc, { upsert: true }).lean().exec(); + await this.sessionModel.replaceOne({ uuid: doc.uuid }, unflatten(doc), { upsert: true }).lean().exec(); return deserialize(Player, flatPlayer); }