TIL/개인 TIL

TIL :: Search

두캔두잇 2023. 11. 15. 16:38

Controller

@Controller('searches')
export class SearchController {
  constructor(private searchService: SearchService) {}

  @Get()
  async searchProduct(@Query() data: ISearchQuery) {
    return await this.searchService.searchProduct(data);
  }
}

 

쿼리 파라미터를 만든 다음에 인터페이스로 타입을 설정 해주었다. 인터페이스에서 정리한 타입들은 아래와 같다.

 

카테고리가 대 - 중 - 소 이렇게 있기때문에 각각의 카테고리들도 타입을 설정해주었다.

 

Service

@Injectable()
export class SearchService {
  constructor(@InjectRepository(Product) private searchRepository: Repository<Product>) {}

  async searchProduct(data: ISearchQuery): Promise<any> {
    console.log(data.product);
    const take = 12;
    const [result, count] = await this.searchRepository.findAndCount({
      take,
      skip: ((data.page || 1) - 1) * take,
      where: {
        name: Like(`%${data.product || ''}%`),
        smallCategory: { id: data.smallCategory, middleCategory: { id: data.middleCategory, largeCategory: { id: data.largeCategory } } },
      },
      relations: ['smallCategory', 'smallCategory.middleCategory', 'smallCategory.middleCategory.largeCategory', 'member'],
    });

    return { data: result, count, page: Number(data.page) || 1 };
  }
}

 

우선 보여줄 상품의 개수를 12개로 설정하고, 페이지네이션을 구현하기 위해 skip에 사용자가 요청한 페이지(data.page) 와 take 값을 이용해 계산을 하도록 했다. 그리고 나서 where절에는 검색조건을 설정했다.  name 이라는 값에 Like 조건을 사용하여 입력한 제품 글자를 포함하는것을 찾도록 조건을 걸었고, 각 카테고리 필드들을 이용해서 선택한 카테고리가 속하는 제품을 검색할 수 있도록 하였다.

 

마지막으로 relations를 통해 관련된 엔티티들을 모두 불러올 수 있게 하였고 return문에 결과,개수,현재페이지 번호를 포함하는 객체를 반환하도록 하였다.