From b4e8cf76f3a7a7e4f08f80e6e75ad24a6a7b3f59 Mon Sep 17 00:00:00 2001 From: Maria Sauer <mcs22@inf.ufpr.br> Date: Mon, 5 May 2025 10:26:21 -0300 Subject: [PATCH] rebaseando com o do thomas --- bun.lockb | Bin 179606 -> 175722 bytes package.json | 3 +- src/routes/search.route.ts | 68 ++++++++++++++++++++++++++------- src/routes/subjects.route.ts | 2 +- src/search/index.ts | 5 ++- src/services/search.service.ts | 68 ++++++++++++++++++--------------- 6 files changed, 98 insertions(+), 48 deletions(-) diff --git a/bun.lockb b/bun.lockb index 07d65b227b112081b8a5c9b3bf38892687972d65..c6fab67ceda4fd6f25551f4c2a416322ac7ac6ae 100755 GIT binary patch delta 32511 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 delta 34419 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%0D6Y9lu0u*}6KR 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 Dog2jP diff --git a/package.json b/package.json index 2cd1559..d60c467 100644 --- a/package.json +++ b/package.json @@ -10,12 +10,13 @@ }, "dependencies": { "@aws-sdk/client-s3": "^3.750.0", + "@elastic/elasticsearch": "^8.17.0", "@hono/swagger-ui": "^0.5.0", "@hono/zod-openapi": "^0.18.3", - "@elastic/elasticsearch": "^8.17.0", "@hono/zod-validator": "^0.2.2", "@scalar/hono-api-reference": "^0.8.0", "archiver": "^7.0.1", + "bun": "1.2.10", "dotenv": "^16.4.5", "dotenv-expand": "^11.0.6", "drizzle-orm": "^0.31.2", diff --git a/src/routes/search.route.ts b/src/routes/search.route.ts index a30fe33..56aad13 100644 --- a/src/routes/search.route.ts +++ b/src/routes/search.route.ts @@ -1,4 +1,4 @@ -import { SearchService } from "@/services/search.service"; +import { SearchService, type ExactFilterFields } from "@/services/search.service"; import Container from "typedi"; // import { honoWithJwt } from ".."; import { Hono } from "hono"; @@ -11,18 +11,58 @@ const searchService = Container.get(SearchService); export const searchRouter = new Hono() .get( '/search', + zValidator( 'query', z.object({ - query: z.string().min(1, 'Query is required'), + query: z.string().optional(), + sortBy: z.enum(['created_at']).optional(), + sortOrder: z.enum(['asc', 'desc']).optional(), + offset: z.coerce.number().int().nonnegative().optional(), + page_size: z.coerce.number().int().positive().optional(), + + // filters + language: z.string().optional(), + objectType: z.string().optional(), + institution: z.string().optional(), }) ), + async (c) => { - try { - const { query } = c.req.valid('query'); + const validated = c.req.valid('query'); + console.log('VALIDATED:', validated); - const results = await searchService.searchIndex(query, {}); + try { + const { + query: rawQuery, + sortBy, + sortOrder = 'desc', + offset = 0, + page_size = 1000, + language, + objectType, + institution, + } = c.req.valid('query'); + + const query = rawQuery ?? ""; + + const filters: Partial<ExactFilterFields> = {}; + if (language) filters.language = language; + if (objectType) filters.objectType = objectType; + if (institution) filters.institution = institution; + + const results = await searchService.searchIndex( + query, + filters, + sortBy, + sortOrder, + undefined, + offset, + page_size + ); + + console.log("results", results) return c.json({ results }); } catch (e) { console.log(e) @@ -41,13 +81,13 @@ export const searchRouter = new Hono() ) .post( - '/index/resource/:id', + '/index/resource/:id', async (c) => { try { const id: number = +c.req.param('id') - + await searchService.indexResource(id); - return c.json({ message: `resource indexed successfully`}); + return c.json({ message: `resource indexed successfully` }); } catch (e) { return c.json( createApexError({ @@ -64,13 +104,13 @@ export const searchRouter = new Hono() ) .post( - '/index/collection/:id', + '/index/collection/:id', async (c) => { try { const id: number = +c.req.param('id') - + await searchService.indexCollection(id); - return c.json({ message: `collection indexed successfully`}); + return c.json({ message: `collection indexed successfully` }); } catch (e) { return c.json( createApexError({ @@ -87,14 +127,14 @@ export const searchRouter = new Hono() ) .post( - '/index/user/:id', + '/index/user/:id', async (c) => { try { const id: number = +c.req.param('id') - + await searchService.indexUser(id); - return c.json({ message: `user indexed successfully`}); + return c.json({ message: `user indexed successfully` }); } catch (e) { return c.json( createApexError({ diff --git a/src/routes/subjects.route.ts b/src/routes/subjects.route.ts index 97ff367..503d76d 100644 --- a/src/routes/subjects.route.ts +++ b/src/routes/subjects.route.ts @@ -94,7 +94,7 @@ export const publicSubjectsRouter = new Hono() async (c) => { try { const subjects = await service.findMany() - return c.json({ subjects }) + return c.json( subjects ) } catch (e) { return c.json( createApexError({ diff --git a/src/search/index.ts b/src/search/index.ts index 3269b06..9f4f054 100644 --- a/src/search/index.ts +++ b/src/search/index.ts @@ -6,6 +6,9 @@ import { Container } from 'typedi' export const es = new Client({ node: env.ELASTICSEARCH_URL, Connection: HttpConnection, + tls: { + rejectUnauthorized: false + } }) // Register the Elasticsearch client in the DI container @@ -26,4 +29,4 @@ checkElasticsearchConnection() export type es = typeof es -export default es \ No newline at end of file +export default es diff --git a/src/services/search.service.ts b/src/services/search.service.ts index 5991e1f..c1cfa73 100644 --- a/src/services/search.service.ts +++ b/src/services/search.service.ts @@ -3,7 +3,7 @@ import es from '@/search' import env from '@/env' import { SearchRepo } from "@/db/repo/search.repo"; -type ExactFilterFields = { +export type ExactFilterFields = { language?: string; objectType?: string; institution?: string; @@ -158,6 +158,41 @@ export class SearchService { ]; } + const searchQuery = query + ? { + multi_match: { + query, + fuzziness: "AUTO", + fields: [ + 'name', + 'author', + 'description', + 'link', + 'fileFormats', + 'educational_stages', + 'languages', + 'subjects', + 'license', + 'object_type', + 'state', + 'user', + 'roles', + 'institution', + 'city', + 'views', + 'downloads', + 'likes', + 'shares', + 'score', + 'comments', + 'created_at' + ], + }, + } + : { + match_all: {}, + } + const result = await this.esClient.search({ index: index, body: { @@ -165,36 +200,7 @@ export class SearchService { size: page_size, query: { bool: { - must: [ - { - multi_match: { - query, - fuzziness: "AUTO", - fields: ['name', - 'author', - 'description', - 'link', - 'fileFormats', - 'educational_stages', - 'languages', - 'subjects', - 'license', - 'object_type', - 'state', - 'user', - 'roles', - 'institution', - 'city', - 'views', - 'downloads', - 'likes', - 'shares', - 'score', - 'comments', - 'created_at'], - }, - }, - ], + must: [searchQuery], filter: filterClauses, }, }, -- GitLab