Node.js와 Mongoose에서 $lookup 대신 ref 및 populate 사용으로 코드 최적화
카테고리
프로그래밍/소프트웨어 개발
서브카테고리
웹 개발
대상자
Node.js 및 MongoDB를 사용하는 중급 이상 개발자, 특히 Mongoose ORM을 활용한 데이터 모델링과 쿼리 작성에 관심 있는 개발자
핵심 요약
- Mongoose의
ref
와populate()
는 코드 가독성을 높이고 데이터 모델을 유지보수하기 쉬운 구조로 만들어준다. $lookup
대신ref
및populate()
를 사용하면 복잡한 쿼리 로직을 간단하게 표현할 수 있다.- CRUD 기반 시스템에서는
ref
와populate()
가 충분하며, 다중 단계 조인이 필요한 경우에만$lookup
을 사용하는 것이 좋다.
섹션별 세부 요약
1. Mongoose에서의 두 가지 데이터 연관 방식
- MongoDB의
$lookup
은 데이터베이스 수준에서 직접 조인을 수행하지만, 코드가 복잡해질 수 있다. - Mongoose의
ref
와populate()
는 모델 간 관계를 명시적으로 정의하고, 쿼리 시 자동으로 관련 데이터를 불러오는 방식이다.
2. `ref` 기반 관계 정의 예시 (Task와 Sprint)
taskSchema
에sprintId
필드를 정의하고,ref: 'sprints'
로 Sprint 모델과 연관시킨다.sprintSchema
의tasks
배열에ref: 'tasks'
로 Task 모델을 참조한다.- 이 방식으로 데이터베이스에서 관계를 명시적으로 설정할 수 있다.
3. `ref` 기반 관계 유지 및 쿼리 예시
- Task 생성 시
sprintId
를 기반으로 Sprint의tasks
배열에 Task ID를 추가한다. - 쿼리 시
Sprint.find().populate('tasks')
로 관련 Task 데이터를 자동으로 불러온다. - 이 방식은 코드가 간결하고, ORM의 장점을 최대한 활용할 수 있다.
4. `ref`와 `populate()`의 장점
- 코드 가독성 향상:
$lookup
보다 훨씬 간결하고 직관적인 표현이 가능하다. - 모델 유지보수 용이: 관계가 명시적으로 정의되어 있어 수정이 용이하다.
- CRUD 시스템에 적합: 단일 단계 조인에 적합하지만, 다중 단계 조인 또는 복잡한 조인에는
$lookup
이 더 효과적이다.
결론
- 대부분의 CRUD 기반 애플리케이션에서는 Mongoose의
ref
와populate()
를 사용해 코드를 간결하게 작성하는 것이 권장된다. - 복잡한 다중 단계 조인이 필요한 경우에만
$lookup
을 사용하는 것이 적절하다. - ORM의 장점을 활용해 데이터베이스 레벨의 관계를 숨기고, 모델 중심의 개발을 추구하는 것이 실무에서 효과적이다.