From 751288e0fb0499daf7b3ee0e5b77e49ee2911625 Mon Sep 17 00:00:00 2001 From: undefined Date: Fri, 25 Oct 2024 06:29:40 +0800 Subject: [PATCH] core: performance update --- packages/hydrooj/src/handler/problem.ts | 3 ++- packages/hydrooj/src/model/document.ts | 5 ++--- packages/hydrooj/src/service/db.ts | 26 ++++++++++++++++++++++++- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/packages/hydrooj/src/handler/problem.ts b/packages/hydrooj/src/handler/problem.ts index b9a22fee8..45f29a21d 100644 --- a/packages/hydrooj/src/handler/problem.ts +++ b/packages/hydrooj/src/handler/problem.ts @@ -149,7 +149,8 @@ export class ProblemMainHandler extends Handler { let [pdocs, ppcount, pcount] = this.queryContext.fail ? [[], 0, 0] : await this.paginate( - problem.getMulti(domainId, query, quick ? ['title', 'pid', 'domainId', 'docId'] : undefined).sort({ sort: 1, docId: 1 }), + problem.getMulti(domainId, query, quick ? ['title', 'pid', 'domainId', 'docId'] : undefined) + .sort({ sort: 1, docId: 1 }).hint('sort'), sort.length ? 1 : page, limit, ); if (total) { diff --git a/packages/hydrooj/src/model/document.ts b/packages/hydrooj/src/model/document.ts index f41bb83dc..f2f72ef5c 100644 --- a/packages/hydrooj/src/model/document.ts +++ b/packages/hydrooj/src/model/document.ts @@ -430,15 +430,14 @@ export async function apply(ctx: Context) { coll.deleteMany({ domainId }), collStatus.deleteMany({ domainId }), ])); + await db.clearIndexes(coll, ['tag', 'hidden']); await db.ensureIndexes( coll, { key: { domainId: 1, docType: 1, docId: 1 }, name: 'basic', unique: true }, { key: { domainId: 1, docType: 1, owner: 1, docId: -1 }, name: 'owner' }, // For problem { key: { domainId: 1, docType: 1, search: 'text', title: 'text' }, name: 'search', sparse: true }, - { key: { domainId: 1, docType: 1, sort: 1, docId: 1 }, name: 'sort', sparse: true }, - { key: { domainId: 1, docType: 1, tag: 1, sort: 1 }, name: 'tag', sparse: true }, - { key: { domainId: 1, docType: 1, hidden: 1, tag: 1, sort: 1 }, name: 'hidden', sparse: true }, + { key: { domainId: 1, docType: 1, sort: 1, docId: 1 }, name: 'sort' }, // For problem solution { key: { domainId: 1, docType: 1, parentType: 1, parentId: 1, vote: -1, docId: -1 }, name: 'solution', sparse: true }, // For discussion diff --git a/packages/hydrooj/src/service/db.ts b/packages/hydrooj/src/service/db.ts index 7693aa0ff..7adfe951b 100644 --- a/packages/hydrooj/src/service/db.ts +++ b/packages/hydrooj/src/service/db.ts @@ -74,6 +74,23 @@ class MongoService { } } + public async clearIndexes(coll: Collection, dropIndex?: string[]) { + if (process.env.NODE_APP_INSTANCE !== '0') return; + let existed: any[]; + try { + existed = await coll.listIndexes().toArray(); + } catch (e) { + existed = []; + } + for (const index of dropIndex) { + const i = existed.find((t) => t.name === index); + if (i) { + logger.info('Drop index %s.%s', coll.collectionName, i.name); + await coll.dropIndex(i.name); + } + } + } + public async ensureIndexes(coll: Collection, ...args: IndexDescription[]) { if (process.env.NODE_APP_INSTANCE !== '0') return; let existed: any[]; @@ -91,7 +108,14 @@ class MongoService { if (!i) { logger.info('Indexing %s.%s with key %o', coll.collectionName, index.name, index.key); await coll.createIndexes([index]); - } else if (i.v < 2 || i.name !== index.name || JSON.stringify(i.key) !== JSON.stringify(index.key)) { + continue; + } + const isDifferent = () => { + if (i.v < 2 || i.name !== index.name || JSON.stringify(i.key) !== JSON.stringify(index.key)) return true; + if (!!i.sparse !== !!index.sparse) return true; + return false; + }; + if (isDifferent()) { if (i.textIndexVersion) { const cur = Object.keys(i.key).filter((t) => !t.startsWith('_')).map((k) => `${k}:${i.key[k]}`); for (const key of Object.keys(i.weights)) cur.push(`${key}:text`);