core: optimize query speed

This commit is contained in:
undefined committed 2021-09-12 05:28:38 +08:00
1 parent f5c63e02ce
commit f1e2409991
20 files changed
+116 -147

No files matched your search

+9 -9
View File
@@ -5,13 +5,13 @@ import moment from 'moment-timezone';
import { ObjectID } from 'mongodb';
import { Time } from '@hydrooj/utils/lib/utils';
import {
BadRequestError,
ContestNotAttendedError, ContestNotFoundError, ContestNotLiveError, InvalidTokenError, PermissionError, ProblemNotFoundError,
RecordNotFoundError,
ValidationError } from '../error';
BadRequestError, ContestNotAttendedError, ContestNotFoundError,
ContestNotLiveError, InvalidTokenError, PermissionError,
ProblemNotFoundError, RecordNotFoundError, ValidationError,
} from '../error';
import {
DomainDoc,
ProblemDoc, Tdoc, User } from '../interface';
DomainDoc, ProblemDoc, Tdoc, User,
} from '../interface';
import paginate from '../lib/paginate';
import { PERM, PRIV } from '../model/builtin';
import * as contest from '../model/contest';
@@ -24,15 +24,15 @@ import * as system from '../model/system';
import user from '../model/user';
import * as bus from '../service/bus';
import {
Handler, param,
Route, Types } from '../service/server';
Handler, param, Route, Types,
} from '../service/server';
import storage from '../service/storage';
export class ContestListHandler extends Handler {
@param('rule', Types.Range(contest.RULES), true)
@param('page', Types.PositiveInt, true)
async get(domainId: string, rule = '', page = 1) {
const cursor = contest.getMulti(domainId, rule ? { rule } : undefined).sort({ beginAt: -1 });
const cursor = contest.getMulti(domainId, rule ? { rule } : undefined);
const qs = rule ? `rule=${rule}` : '';
const [tdocs, tpcount] = await paginate(cursor, page, system.get('pagination.contest'));
const tids = [];
+11 -45
View File
@@ -1,9 +1,9 @@
import { Dictionary } from 'lodash';
import moment from 'moment-timezone';
import {
DomainJoinAlreadyMemberError, DomainJoinForbiddenError,
InvalidJoinInvitationCodeError,
RoleAlreadyExistError, ValidationError } from '../error';
DomainJoinAlreadyMemberError, DomainJoinForbiddenError, InvalidJoinInvitationCodeError,
RoleAlreadyExistError, ValidationError,
} from '../error';
import type { DomainDoc } from '../interface';
import avatar from '../lib/avatar';
import paginate from '../lib/paginate';
@@ -16,15 +16,15 @@ import { DOMAIN_SETTINGS, DOMAIN_SETTINGS_BY_KEY } from '../model/setting';
import * as system from '../model/system';
import user from '../model/user';
import {
Handler, param, post,
query, Route, Types } from '../service/server';
Handler, param, post, query, Route, Types,
} from '../service/server';
import { log2 } from '../utils';
class DomainRankHandler extends Handler {
@query('page', Types.PositiveInt, true)
async get(domainId: string, page = 1) {
const [dudocs, upcount, ucount] = await paginate(
domain.getMultiUserInDomain(domainId, { uid: { $nin: [0, 1] } }).sort({ rp: -1 }),
domain.getMultiUserInDomain(domainId, { uid: { $gt: 1 } }).sort({ rp: -1 }),
page,
100,
);
@@ -33,13 +33,9 @@ class DomainRankHandler extends Handler {
udocs.push(user.getById(domainId, dudoc.uid));
}
udocs = await Promise.all(udocs);
const path = [
['Hydro', 'homepage'],
['ranking', null],
];
this.response.template = 'ranking.html';
this.response.body = {
udocs, upcount, ucount, page, path,
udocs, upcount, ucount, page,
};
}
}
@@ -55,13 +51,8 @@ class ManageHandler extends Handler {
class DomainEditHandler extends ManageHandler {
async get() {
const path = [
['Hydro', 'homepage'],
['domain', null],
['domain_edit', null],
];
this.response.template = 'domain_edit.html';
this.response.body = { current: this.domain, settings: DOMAIN_SETTINGS, path };
this.response.body = { current: this.domain, settings: DOMAIN_SETTINGS };
}
async post(args) {
@@ -76,13 +67,8 @@ class DomainEditHandler extends ManageHandler {
class DomainDashboardHandler extends ManageHandler {
async get() {
const path = [
['Hydro', 'homepage'],
['domain', null],
['domain_dashboard', null],
];
this.response.template = 'domain_dashboard.html';
this.response.body = { domain: this.domain, path };
this.response.body = { domain: this.domain };
}
async postInitDiscussionNode({ domainId }) {
@@ -165,9 +151,7 @@ class DomainPermissionHandler extends ManageHandler {
const perms = this.request.body[role] instanceof Array
? this.request.body[role]
: [this.request.body[role]];
// @ts-expect-error
roles[role] = 0n;
// @ts-expect-error
for (const r of perms) roles[role] |= 1n << BigInt(r);
}
await domain.setRoles(domainId, roles);
@@ -178,13 +162,8 @@ class DomainPermissionHandler extends ManageHandler {
class DomainRoleHandler extends ManageHandler {
async get({ domainId }) {
const roles = await domain.getRoles(domainId, true);
const path = [
['Hydro', 'homepage'],
['domain', null],
['domain_role', null],
];
this.response.template = 'domain_role.html';
this.response.body = { roles, domain: this.domain, path };
this.response.body = { roles, domain: this.domain };
}
@param('role', Types.Name)
@@ -220,11 +199,6 @@ class DomainJoinApplicationsHandler extends ManageHandler {
delete this.response.body.expirations[domain.JOIN_EXPIRATION_KEEP_CURRENT];
}
this.response.body.url_prefix = (this.domain.host || [])[0] || system.get('server.url');
this.response.body.path = [
['Hydro', 'homepage'],
['domain', null],
['domain_join_applications', null],
];
this.response.template = 'domain_join_applications.html';
}
@@ -255,11 +229,7 @@ class DomainJoinApplicationsHandler extends ManageHandler {
class DomainJoinHandler extends Handler {
joinSettings: any;
constructor(ctx) {
super(ctx);
this.noCheckPermView = true;
}
noCheckPermView = true;
async prepare() {
const r = await domain.getRoles(this.domain);
@@ -274,10 +244,6 @@ class DomainJoinHandler extends Handler {
this.response.template = 'domain_join.html';
this.response.body.joinSettings = this.joinSettings;
this.response.body.code = code;
this.response.body.path = [
['Hydro', 'homepage'],
['domain_join', 'domain_join', { domainId, code }],
];
}
@param('code', Types.Content, true)
+8 -8
View File
@@ -1,10 +1,10 @@
import yaml from 'js-yaml';
import { ObjectID } from 'mongodb';
import {
BlacklistedError,
DomainAlreadyExistsError, InvalidTokenError,
NotFoundError, PermissionError,
UserAlreadyExistError, UserNotFoundError, ValidationError, VerifyPasswordError } from '../error';
BlacklistedError, DomainAlreadyExistsError, InvalidTokenError,
NotFoundError, PermissionError, UserAlreadyExistError,
UserNotFoundError, ValidationError, VerifyPasswordError,
} from '../error';
import { DomainDoc, MessageDoc, Setting } from '../interface';
import avatar from '../lib/avatar';
import { md5 } from '../lib/crypto';
@@ -25,7 +25,7 @@ import * as training from '../model/training';
import user from '../model/user';
import * as bus from '../service/bus';
import {
Connection, ConnectionHandler, Handler, param, Route, Types,
Connection, ConnectionHandler, Handler, param, Route, Types,
} from '../service/server';
const { geoip, useragent } = global.Hydro.lib;
@@ -40,7 +40,7 @@ class HomeHandler extends Handler {
async getHomework(domainId: string, limit: number = 5) {
if (this.user.hasPerm(PERM.PERM_VIEW_HOMEWORK)) {
const tdocs = await contest.getMulti(domainId, {}, document.TYPE_HOMEWORK)
.sort('beginAt', -1).limit(limit).toArray();
.limit(limit).toArray();
const tsdict = await contest.getListStatus(
domainId, this.user._id,
tdocs.map((tdoc) => tdoc.docId), document.TYPE_HOMEWORK,
@@ -53,7 +53,7 @@ class HomeHandler extends Handler {
async getContest(domainId: string, limit: number = 10) {
if (this.user.hasPerm(PERM.PERM_VIEW_CONTEST)) {
const tdocs = await contest.getMulti(domainId)
.sort('beginAt', -1).limit(limit).toArray();
.limit(limit).toArray();
const tsdict = await contest.getListStatus(
domainId, this.user._id, tdocs.map((tdoc) => tdoc.docId),
);
@@ -88,7 +88,7 @@ class HomeHandler extends Handler {
async getRanking(domainId: string, limit: number = 50) {
if (this.user.hasPerm(PERM.PERM_VIEW_RANKING)) {
const dudocs = await domain.getMultiUserInDomain(domainId, { uid: { $nin: [0, 1] } })
const dudocs = await domain.getMultiUserInDomain(domainId, { uid: { $gt: 1 } })
.sort({ rp: -1 }).project({ uid: 1 }).limit(limit).toArray();
const uids = dudocs.map((dudoc) => dudoc.uid);
this.collectUser(uids);
+3 -4
View File
@@ -14,8 +14,8 @@ import TaskModel from '../model/task';
import user from '../model/user';
import * as bus from '../service/bus';
import {
Connection, ConnectionHandler, Handler, param,
Route, Types } from '../service/server';
Connection, ConnectionHandler, Handler, param, Route, Types,
} from '../service/server';
import { buildProjection } from '../utils';
import { postJudge } from './judge';
@@ -57,9 +57,8 @@ class RecordListHandler extends Handler {
if (status) q.status = status;
if (all) {
this.checkPriv(PRIV.PRIV_MANAGE_ALL_DOMAIN);
q.domainId = { $exists: true };
}
let cursor = record.getMulti(domainId, q).sort('_id', -1);
let cursor = record.getMulti(all ? '' : domainId, q).sort('_id', -1);
if (!full) cursor = cursor.project(buildProjection(record.PROJECTION_LIST));
const limit = full ? 10 : system.get('pagination.record');
const rdocs = invalid