| 54 | } |
| 55 | |
| 56 | const defaultSearch = async (domainId: string, q: string, options?: ProblemSearchOptions) => { |
| 57 | const escaped = escapeRegExp(q.toLowerCase()); |
| 58 | const projection: (keyof ProblemDoc)[] = ['domainId', 'docId', 'pid']; |
| 59 | const $regex = new RegExp(q.length >= 2 ? escaped : `\\A${escaped}`, 'gim'); |
| 60 | const filter = { $or: [{ pid: { $regex } }, { title: { $regex } }, { tag: q }] }; |
| 61 | const pdocs = await problem.getMulti(domainId, filter, projection) |
| 62 | .skip(options.skip || 0).limit(options.limit || system.get('pagination.problem')).toArray(); |
| 63 | if (!options.skip) { |
| 64 | let pdoc = await problem.get(domainId, Number.isSafeInteger(+q) ? +q : q, projection); |
| 65 | if (pdoc) pdocs.unshift(pdoc); |
| 66 | else if (/^P\d+$/.test(q)) { |
| 67 | pdoc = await problem.get(domainId, +q.substring(1), projection); |
| 68 | if (pdoc) pdocs.unshift(pdoc); |
| 69 | } |
| 70 | } |
| 71 | return { |
| 72 | hits: Array.from(new Set(pdocs.map((i) => `${i.domainId}/${i.docId}`))), |
| 73 | total: Math.max(pdocs.length, await problem.count(domainId, filter)), |
| 74 | countRelation: 'eq', |
| 75 | }; |
| 76 | }; |
| 77 | |
| 78 | export interface QueryContext { |
| 79 | query: Filter<ProblemDoc>; |