diff --git a/apps/portal/prisma/migrations/20221014105030_add_question_content_search/migration.sql b/apps/portal/prisma/migrations/20221014105030_add_question_content_search/migration.sql new file mode 100644 index 00000000..992d2a77 --- /dev/null +++ b/apps/portal/prisma/migrations/20221014105030_add_question_content_search/migration.sql @@ -0,0 +1,8 @@ +-- AlterTable +ALTER TABLE "QuestionsQuestion" ADD COLUMN "contentSearch" TSVECTOR + GENERATED ALWAYS AS + to_tsvector('english', coalesce(content, '')) + STORED; + +-- CreateIndex +CREATE INDEX "QuestionsQuestion_contentSearch_idx" ON "QuestionsQuestion" USING GIN("textSearch"); \ No newline at end of file diff --git a/apps/portal/prisma/schema.prisma b/apps/portal/prisma/schema.prisma index 9ce74736..61e45c6c 100644 --- a/apps/portal/prisma/schema.prisma +++ b/apps/portal/prisma/schema.prisma @@ -374,6 +374,10 @@ model QuestionsQuestion { votes QuestionsQuestionVote[] comments QuestionsQuestionComment[] answers QuestionsAnswer[] + + contentSearch Unsupported("TSVECTOR")? + + @@index([contentSearch]) } model QuestionsQuestionEncounter { diff --git a/apps/portal/src/server/router/questions-question-router.ts b/apps/portal/src/server/router/questions-question-router.ts index 2cb564d3..353ac4a3 100644 --- a/apps/portal/src/server/router/questions-question-router.ts +++ b/apps/portal/src/server/router/questions-question-router.ts @@ -182,6 +182,31 @@ export const questionsQuestionRouter = createProtectedRouter() return question; }, }) + .query('getRelatedQuestionsByContent', { + input: z.object({ + content: z.string(), + pageNum: z.number(), + pageSize: z.number(), + }), + async resolve({ ctx, input }) { + const escapeChars = /[()|&:*!]/g; + + const query = + input.content + .replace(escapeChars, " ") + .trim() + .split(/\s+/) + .join(" | "); + + const res = await ctx.prisma.$queryRaw` + SELECT content FROM "Post" + WHERE + "contentSearch" @@ to_tsquery('english', ${query}) + ORDER BY ts_rank("textSearch", to_tsquery('english', ${query})) DESC + LIMIT 10; + `; + } + }) .mutation('create', { input: z.object({ company: z.string(),