diff --git a/api/src/search/controller.ts b/api/src/search/controller.ts index 0bbb74e0..1af74d21 100644 --- a/api/src/search/controller.ts +++ b/api/src/search/controller.ts @@ -1,6 +1,6 @@ -import { Controller, Get } from "routing-controllers"; +import { Controller, Get, QueryParams } from "routing-controllers"; -import { GetSearchResponse } from "./types"; +import { SearchQuery, SearchResponse } from "./types"; import { SearchService } from "./service"; import { Service } from "typedi"; @@ -10,8 +10,8 @@ export class SearchController { constructor(private readonly searchService: SearchService) {} @Get("/") - public async search(): Promise { - const searchResults = await this.searchService.search("test"); + public async search(@QueryParams() req: SearchQuery): Promise { + const searchResults = await this.searchService.search(req.query, req.limit); return { searchResults, }; diff --git a/api/src/search/service.ts b/api/src/search/service.ts index 9bb147e6..b72b9acb 100644 --- a/api/src/search/service.ts +++ b/api/src/search/service.ts @@ -25,11 +25,21 @@ export class SearchService { }); } - public search = async (query: string): Promise => { - this.logger.info({ message: `Searching for ${query}` }); - return { - results: [], - }; + public search = async (q: string, limit?: number): Promise => { + this.logger.info({ message: `Searching for "${q}" in all indexes` }); + const searchResults = await this.meilisearch.multiSearch({ + queries: [ + { indexUid: "project", q, limit, attributesToRetrieve: ["id", "name"] }, + { + indexUid: "contribution", + q, + limit, + attributesToRetrieve: ["id", "title", "type", "activityCount"], + }, + { indexUid: "contributor", q, limit, attributesToRetrieve: ["id", "name", "avatarUrl"] }, + ], + }); + return searchResults as SearchResults; }; public upsert = async (index: SearchType, data: T): Promise => { diff --git a/api/src/search/types.ts b/api/src/search/types.ts index 46f846fd..e2b752e1 100644 --- a/api/src/search/types.ts +++ b/api/src/search/types.ts @@ -3,8 +3,18 @@ import { ContributorEntity } from "@dzcode.io/models/dist/contributor"; import { GeneralResponse } from "src/app/types"; import { MultiSearchResponse } from "meilisearch"; import { ProjectEntity } from "@dzcode.io/models/dist/project"; +import { IsNotEmpty, IsPositive, IsString } from "class-validator"; -export interface GetSearchResponse extends GeneralResponse { +export class SearchQuery { + @IsString() + @IsNotEmpty() + query!: string; + + @IsPositive() + limit: number = 5; +} + +export interface SearchResponse extends GeneralResponse { searchResults: SearchResults; }