From b5208c2ad052ed318d75b8c85cd0463b25cf1ace Mon Sep 17 00:00:00 2001 From: PrivateGER Date: Wed, 19 Feb 2025 16:26:02 +0100 Subject: [PATCH] simplify tsvector implementation, remove cover density --- packages/backend/src/core/SearchService.ts | 61 ++-------------------- 1 file changed, 5 insertions(+), 56 deletions(-) diff --git a/packages/backend/src/core/SearchService.ts b/packages/backend/src/core/SearchService.ts index c99944fa51..2934d08c2d 100644 --- a/packages/backend/src/core/SearchService.ts +++ b/packages/backend/src/core/SearchService.ts @@ -240,7 +240,8 @@ export class SearchService { ): Promise { switch (this.provider) { case 'sqlLike': - case 'sqlPgroonga': { + case 'sqlPgroonga': + case 'tsvector': { // ほとんど内容に差がないのでsqlLikeとsqlPgroongaを同じ処理にしている. // 今後の拡張で差が出る用であれば関数を分ける. return this.searchNoteByLike(q, me, opts, pagination); @@ -248,9 +249,6 @@ export class SearchService { case 'meilisearch': { return this.searchNoteByMeiliSearch(q, me, opts, pagination); } - case 'tsvector': { - return this.searchNoteByTsvector(q, me, opts, pagination); - } default: { // eslint-disable-next-line @typescript-eslint/no-unused-vars const typeCheck: never = this.provider; @@ -259,57 +257,6 @@ export class SearchService { } } - @bindThis - private async searchNoteByTsvector(q: string, - me: MiUser | null, - opts: SearchOpts, - pagination: SearchPagination, - ): Promise { - const query = this.queryService.makePaginationQuery(this.notesRepository.createQueryBuilder('note'), pagination.sinceId, pagination.untilId); - - if (opts.userId) { - query.andWhere('note.userId = :userId', { userId: opts.userId }); - } else if (opts.channelId) { - query.andWhere('note.channelId = :channelId', { channelId: opts.channelId }); - } - - query - .innerJoinAndSelect('note.user', 'user') - .leftJoinAndSelect('note.reply', 'reply') - .leftJoinAndSelect('note.renote', 'renote') - .leftJoinAndSelect('reply.user', 'replyUser') - .leftJoinAndSelect('renote.user', 'renoteUser'); - - query.andWhere('note.tsvector_embedding @@ websearch_to_tsquery(:q)', { q }); - - if (opts.order === 'asc') { - query - .addSelect('ts_rank_cd(note.tsvector_embedding, websearch_to_tsquery(:q))', 'rank') - .orderBy('rank', 'DESC'); - } else { - query - .orderBy('note.created_at', 'DESC'); - } - - if (opts.host) { - if (opts.host === '.') { - query.andWhere('note.userHost IS NULL'); - } else { - query.andWhere('note.userHost = :host', { host: opts.host }); - } - } - - if (opts.filetype) { - query.andWhere('note."attachedFileTypes" && :types', { types: fileTypes[opts.filetype] }); - } - - this.queryService.generateVisibilityQuery(query, me); - if (me) this.queryService.generateMutedUserQuery(query, me); - if (me) this.queryService.generateBlockedUserQuery(query, me); - - return await query.limit(pagination.limit).getMany(); - } - @bindThis private async searchNoteByLike( q: string, @@ -333,7 +280,9 @@ export class SearchService { .leftJoinAndSelect('renote.user', 'renoteUser'); if (this.config.fulltextSearch?.provider === 'sqlPgroonga') { - query.andWhere('note.text &@~ :q', { q }); + query.andWhere('note.text &@~ :q', {q}); + } else if (this.config.fulltextSearch?.provider === "tsvector") { + query.andWhere('note.tsvector_embedding @@ websearch_to_tsquery(:q)', { q }); } else { query.andWhere('note.text ILIKE :q', { q: `%${ sqlLikeEscape(q) }%` }); }