일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 그래프
- Crawling
- 자바스크립트
- Node.js
- Nestjs
- 수학
- 타입 챌린지
- BFS
- 소켓
- 알고리즘
- 백준
- 쉬운 문제
- javascript
- ip
- 타입스크립트
- HTTP
- 크롤링
- socket
- Algorithm
- 프로그래머스 레벨 2
- dfs
- type challenge
- typescript
- 문자열
- TCP
- 가천대
- HTTP 완벽 가이드
- dp
- 프로그래머스
- 레벨 1
- Today
- Total
kakasoo
TypeORM, 집계함수(sum, count)와 orderBy 사용하기 본문
I agree with you. There is a problem here. LoadRelationCountAndMap is mapped, but does not work properly when sorted, and addSelect is not mapped, but can be sorted. Eventually, there is a problem of having to use both.
query
.loadRelationCountAndMap('user.itemCount', 'user.items', 'itemCount') // mapped, but can't be sorted.
.addSelect((qb) => {
return qb.select('COUNT(item.id)', 'count').from(ItemEntity, 'item'); // can't be mapped, but can be sorted. ( getMany )
}, 'count')
.orderBy('count', 'DESC');
I hope that it help other people.
addSelect와 loadRelationCountAndMap의 차이
안타깝게도 TypeORM에서는 Repository 패턴으로는 집계함수들을 사용할 수 없다. Entity를 세는 방법은 있지만, Join된 테이블에 대해서는 불가능하고, 그마저도 완벽하지 못하다. 그래서 울며 겨자먹기로 queryBuilder를 사용한 후, loadRelationCountAndMap을 써야 하는데, 이 경우에는 객체에 mapping은 되지만, 이후 로직에서 alias로 잡는 것이 불가능하다. 즉, 추가적인 쿼리문의 작성이 불가능한데, 이로 인해 아래와 같은 문제가 생긴다.
- loadRelationAndCountAndMap으로, 게시글의 댓글을 count 하여 조회.
- 모든 게시글을 조회하는 것은 DB에 부담이 크기 때문에 페이지네이션으로 구현. ( skip, limit )
- 여기서 댓글 수를 기준으로 정렬하여 조회할 방법이 없다. ( alias로 지정한 문자열을 통해 추가적인 쿼리 작성이 불가능하기 때문 )
반대로 addSelect는 alias를 잡을 수는 있지만, getOne, getMany를 사용할 때 mapping이 안 된다. 따라서, 객체의 매핑과 정렬을 동시에 하고 싶다면, addSelect를 함께 써주어야 한다. 사실, 같은 데이터를 가져오는 것이기 때문에 이 둘을 동시에 사용하는 것은 불필요한 서브 쿼리문을 작성하는 것과 마찬가지지만, 현재 TypeORM에서는 이게 최선으로 보인다.
TypeORM의 한계?
아쉽게도, 지금은 TypeORM을 쓰면서 개발자의 창의성이 요구된다. 창의성이 요구된다는 것은, 자유도가 높아 표준이랄 게 없는 상황이거나, 아니면 도리어 자유도가 너무 낮아 개발자들이 직접 해결책을 강구하는 경우다. TypeORM은 후자다. 상용화된 프로그램에 사용하는 데에 지장이랄 것은 없지만, 생태계가 더 발전해야 할 필요성이 느껴진다.
loadRelationCountAndMap 그냥 쓰지 말자!
만약 loadRelationCountAndMap을 버리고 where문에는 서브쿼리를,
count한 값을 프로퍼티로 추가해야 한다면 getRawOne, getRawMany를 쓴다면 이 문제를 해결할 수는 있다.
다만 raw한 방식이라 취향이 조금 갈릴 수는 있겠다.
'프로그래밍 > NestJS' 카테고리의 다른 글
한 가지 인스턴스로만 이루어진 순수한 배열로 타입을 확정하기 (0) | 2022.07.05 |
---|---|
Nest.js POST 메서드에서의 Redirect ( GET이 아닌 메서드에서의 ) (0) | 2022.06.19 |
CannotExecuteNotConnectedError & medata was not found (0) | 2022.06.14 |
Repository 최대한 예쁘게 써보기 ( 검색, 정렬, 필터링 ) (2) | 2022.06.11 |
컨벤션을 어떻게 정하는가 / 팀을 돌아보며 (0) | 2022.06.07 |