Nestjs 검색 기능 만들기

jonghyun.log·2022년 4월 9일
0

nestjs 개발

목록 보기
3/4

검색 기능 설명

저번에 만들었던 페이지네이션에 검색 기능을 추가하려고 한다.
입력으로 쿼리문을 사용해서 요구사항을 받아줄건데 크게 다음의 세개의 기능을 넣어서 구현하려고 한다.

  • 카테고리(category) : 카테고리를 입력하면 원하는 카테고리에서만 데이터를 가져오기
  • 분류하기(sortBy) : 신상품순, 낮은가격순, 판매량많은순 이렇게 세가지 기준으로 분류
  • 검색하기(name) : 검색어를 입력하면 검색어가 들어간 데이터만 가져오기

입력데이터 예시) url/goods?category=SHIRTS?name=stripe?sortBy=BEST
이런 url으로 데이터를 요청하면 카테고리가 셔츠이고 이름에 stripe가 들어가고 판매량 많은 순으로 데이터를 출력해주면 된다.

구현

자 이제 요구사항대로 직접 구현해보자.

async searchGoods(page: SearchGoodsDto) {
    //쿼리로 category가 들어있으면 카테고리에 맞는것들만 가져와야함
    const { sortBy, category, name } = page;
    console.log(page);
    /**total : 물품갯수 카운트, sortObj : 분류기준 , found : 찾은 물풀들 */
    let total, sortObj, found;
    if (!sortBy) {
      //sortBy가 비어있으면 분류를 안함
    } else {
      switch (sortBy) {
        case SortMethod.BEST:
          sortObj = { sellnum: 'DESC' };
          break;
        case SortMethod.LOWPRICE:
          sortObj = { price: 'ASC' };
          break;
        case SortMethod.NEW:
          sortObj = { createdAt: 'DESC' };
          break;
      }
    }
    if (!category) {
      //category가 비어있을때
      total = await this.goodsRepository.count();
      found = await this.getPagination(page, sortObj, name);
    } else {
      //category가 들어있을 때
      /**카테고리에 알맞은 데이터 전체 갯수 세기 */
      total = await this.goodsRepository.count({ category });
      found = await this.getPaginationByCategory(page, category, sortObj, name);
    }
    return new Page(total, page.pageSize, found);
  }

  /**카테고리에 따른 페이지네이션*/
  async getPaginationByCategory(page, category, sortObj, name) {
    const goods = await this.goodsRepository.find({
      where: { category, name: Like(`%${name}%`) },
      take: page.getLimit(),
      skip: page.getOffset(),
      order: sortObj,
    });
    return goods;
  }
  /**카테고리 없이 페이지네이션 */
  async getPagination(page, sortObj, name) {
    console.log(sortObj);
    const goods = await this.goodsRepository.find({
      where: { name: Like(`%${name}%`) },
      take: page.getLimit(),
      skip: page.getOffset(),
      order: sortObj,
    });
    return goods;
  }

분류기준 처리(sortBy)

먼저 요청한 url의 쿼리를 컨트롤러에서 받아서 page라는 변수에 저장해놓은 다음,
분류기준이 판매량많은순(BEST), 낮은가격순(LOWPRICE), 신상품순(NEW)인지 스위치문에서 체크를 해준다.

if (!sortBy) {
      //sortBy가 비어있으면 분류를 안함
    } else {
      switch (sortBy) {
        case SortMethod.BEST:
          sortObj = { sellnum: 'DESC' };
          break;
        case SortMethod.LOWPRICE:
          sortObj = { price: 'ASC' };
          break;
        case SortMethod.NEW:
          sortObj = { createdAt: 'DESC' };
          break;
      }
    }

카테고리 처리(category)

카테고리를 쿼리에 넣지않아도 데이터를 불러올수있게 로직을 만들었기 때문에, category가 있을 때와 없을 때를 각각 처리해주었다.

if (!category) {
      //category가 비어있을때
      total = await this.goodsRepository.count();
      found = await this.getPagination(page, sortObj, name);
    } else {
      //category가 들어있을 때
      /**카테고리에 알맞은 데이터 전체 갯수 세기 */
      total = await this.goodsRepository.count({ category });
      found = await this.getPaginationByCategory(page, category, sortObj, name);
    }

카테고리가 없을 때

카테고리가 없을 때는 카테고리 없이 find매서드 옵션을 주어서 원하는 값들을 찾아준다.
이때 검색어로 받은 name은 where 옵션의 Like함수로 처리한다.

(find에 관한 더 자세한 정보는 다음의 링크 참조 typeorm-find)

/**카테고리 없이 페이지네이션 */
  async getPagination(page, sortObj, name) {
    console.log(sortObj);
    const goods = await this.goodsRepository.find({
      where: { name: Like(`%${name}%`) },
      take: page.getLimit(),
      skip: page.getOffset(),
      order: sortObj,
    });
    return goods;
  }

카테고리가 있을 때

카테고리가 있을 때는 카테고리가 없을 때에 find 옵션으로 category만 추가해서 원하는 값들을 찾아주면 된다.

/**카테고리에 따른 페이지네이션*/
  async getPaginationByCategory(page, category, sortObj, name) {
    const goods = await this.goodsRepository.find({
      where: { category, name: Like(`%${name}%`) },
      take: page.getLimit(),
      skip: page.getOffset(),
      order: sortObj,
    });
    return goods;
  }

완성!

결과물

원하는대로 구현이 된것을 확인할 수 있다!

0개의 댓글