ElasticSearch 사용하지 않고 Search API 작성

ElasticSearch를 사용하지 않고, 단어 기반의 통합 검색 기능을 추가해야하는 일이 생겼다.

통합검색 API를 구축할 때, 맨처음에는 다음과 같이 @Body 를 사용하여 body안에 {word: 단어}를 포함시켜 API를 호출하는 방식으로 설계하였다.

// @Body를 사용하였을 때
@Get('')
search(@Body(){word: string}){
	return this.service.search(word);
}

위의 코드처럼 작성하고 테스트 했을 때, word를 undefined로 호출시 백엔드로 전달이 되지않는 이슈가 있었다.

 

구글은 어떤 방식으로 하는지 궁금해서 구글에 검색을 해보고 url을 중점적으로 확인하였다.

Google에 NestJs검색하였을 때 나타난 URL

구글의 검색 URL을 보고 @Query를 사용하여 API의 url뒤에 ?를 붙여서 'http://localhost?word={검색하려는 단어}'와 같이 구성하였다.

  @Get('?')
  async search(@Query('word') word: string) {
    const searchWithUser = await this.userService.findByUserName(word);
    const searchWithTag = await this.tagService.findByWord(word);
    const searchWithStoryTitle = await this.storyService.findByWord(word);
    const searchWithProductTitle = await this.productService.findByWord(word);
    const SearchedTagStory = await this.tagStoryService.findByTagId(
      searchWithTag,
    );
    const findStoryWithStoryId = await this.storyService.findByStoryId(
      searchWithStoryTitle,
    );
    const findStoryWithProductId = await this.storyService.findByProductId(
      searchWithProductTitle,
    );
    const findStoryWithTagId = await this.storyService.findByTagStoryIds(
      SearchedTagStory,
    );

    if (
      !searchWithUser &&
      !findStoryWithStoryId &&
      !findStoryWithProductId &&
      !findStoryWithTagId
    ) {
      return null;
    } else {
      const result = [
        ...searchWithUser,
        ...findStoryWithStoryId,
        ...findStoryWithProductId,
        ...findStoryWithTagId,
      ];
      const SetResult = new Set(result);
      return SetResult;
    }

API 작동 방식은 어떻게보면 단순무식하게 보일 수도 있는데 @Query로 입력받은 단어로 관련 테이블 4개에 쿼리를 날려서 받아온 정보를 Set( )을 통해 중복 제거하고 리턴하는 것이다.