diff --git a/packages/flexsearch/index.ts b/packages/flexsearch/index.ts new file mode 100644 index 000000000..940c01286 --- /dev/null +++ b/packages/flexsearch/index.ts @@ -0,0 +1,69 @@ +import Document from 'flexsearch/src/document'; +import * as cjk from 'flexsearch/src/lang/cjk/default'; +import { + _, buildProjection, Context, DocumentModel, Logger, SystemModel, +} from 'hydrooj'; + +const logger = new Logger('flexsearch'); + +export async function apply(ctx: Context) { + logger.info('Building index...'); + const index = new Document({ + ...cjk, + tokenize: 'strict', + // optimize: true, + // resolution: 9, + document: { + id: 'id', + tag: 'domainId', + index: [{ + field: 'title', + tokenize: 'full', + }], + }, + worker: true, + }) as any; + const pdocs = await DocumentModel.coll.find({ docType: 10 }) + .project(buildProjection(['docId', 'pid', 'domainId', 'title'])) + .toArray(); + for (const pdoc of pdocs as any[]) { + pdoc.id = `${pdoc.domainId}/${pdoc.docId}`; + delete pdoc._id; + delete pdoc.docId; + index.add(pdoc); + } + logger.success('Index built.'); + try { + await index.searchAsync('a', { tag: 'system', limit: 1 }); + } catch (e) { + logger.error('Failed to perform search operation.'); + logger.error(e); + return; + } + global.Hydro.lib.problemSearch = async (domainId, query, opts) => { + const limit = opts?.limit || SystemModel.get('pagination.problem'); + const ids = await index.searchAsync(query, { tag: domainId, limit })[0]?.result || []; + return { + countRelation: 'eq', + total: ids.length, + hits: ids, + }; + }; + + ctx.on('problem/add', async (doc, docId) => { + const pdoc = _.pick(doc, ['pid', 'domainId', 'title']) as any; + pdoc.id = `${doc.domainId}/${docId}`; + index.add(pdoc); + }); + + ctx.on('problem/edit', async (doc) => { + const pdoc = _.pick(doc, ['pid', 'domainId', 'title']) as any; + pdoc.id = `${doc.domainId}/${doc.docId}`; + index.remove(pdoc.id); + index.add(pdoc); + }); + + ctx.on('problem/del', async (domainId, docId) => { + index.remove(`${domainId}/${docId}`); + }); +} diff --git a/packages/flexsearch/package.json b/packages/flexsearch/package.json new file mode 100644 index 000000000..92ca68d6e --- /dev/null +++ b/packages/flexsearch/package.json @@ -0,0 +1,7 @@ +{ + "name": "@hydrooj/flexsearch", + "version": "0.0.1", + "dependencies": { + "flexsearch": "^0.7.31" + } +}