diff --git a/packages/sonic/index.ts b/packages/sonic/index.ts index ea6f67566..2fd9014a4 100644 --- a/packages/sonic/index.ts +++ b/packages/sonic/index.ts @@ -1,6 +1,6 @@ import { Context, DomainModel, iterateAllProblem, iterateAllProblemInDomain, - Logger, Schema, SystemModel, + Logger, ProblemModel, Schema, SystemModel, } from 'hydrooj'; import { SonicService } from './service'; @@ -11,12 +11,22 @@ export function apply(ctx: Context) { global.Hydro.lib.problemSearch = async (domainId, query, opts) => { const limit = opts?.limit || SystemModel.get('pagination.problem'); - const ids = await ctx.sonic.query('problem', `${domainId}@title`, query, { limit }); - if (limit - ids.length > 0) ids.push(...await ctx.sonic.query('problem', `${domainId}@content`, query, { limit: limit - ids.length })); + let hits = await ctx.sonic.query('problem', `${domainId}@title`, query, { limit }); + if (!opts.skip) { + let pdoc = await ProblemModel.get(domainId, +query || query, ProblemModel.PROJECTION_LIST); + if (pdoc) { + hits = hits.filter((i) => i !== `${pdoc.domainId}/${pdoc.docId}`); + hits.unshift(`${pdoc.domainId}/${pdoc.docId}`); + } else if (/^P\d+$/.test(query)) { + pdoc = await ProblemModel.get(domainId, +query.substring(1), ProblemModel.PROJECTION_LIST); + if (pdoc) hits.unshift(`${pdoc.domainId}/${pdoc.docId}`); + } + } + if (limit - hits.length > 0) hits.push(...await ctx.sonic.query('problem', `${domainId}@content`, query, { limit: limit - hits.length })); return { - countRelation: ids.length >= limit ? 'gte' : 'eq', - total: ids.length, - hits: ids, + countRelation: hits.length >= limit ? 'gte' : 'eq', + total: hits.length, + hits, }; }; diff --git a/packages/sonic/package.json b/packages/sonic/package.json index 5e0b5dba1..4e6992a8c 100644 --- a/packages/sonic/package.json +++ b/packages/sonic/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/sonic", - "version": "1.3.1", + "version": "1.3.2", "description": "Sonic search service", "main": "index.ts", "preferUnplugged": true,