이번에 사이드 프로젝트를 하며 검색 기능을 구현하게 되었는데 이때 Mongoose 의 aggregate 메소드를 사용했다.
검색 기능 구현을 위해 Atlas Search 를 이용했는데, 이를 이용하려면 데이터 조회 시 find 대신 aggregate를 사용해야 했다. ($search)
구현을 위해 알아본 aggregate 에 대한 정보를 find 와 비교하여 정리했다.
1. aggregate 란
aggregate 는 모으다, 집합, 집계 등의 의미를 가지고 있는 단어이다. Mongoose 에서는 find 와 같이 데이터를 조회할 때 사용하는 메소드이지만 find 보다 더 복잡한 처리를 지원하는 파이프라인 메소드라고 이해하면 된다.
복잡한 계산, 변형, 조인, 통계 분석에 최적화되어있다.
2. aggregate 매개변수
aggregate() 는 매개변수로 배열을 받는다. 배열 안에는 다양한 연산자가 올 수 있는데 aggregate 는 이 연산자들을 순차적으로 처리한다.
아래 코드는 Model 에서 이름이 'Junseo' 인($match) Document 에서 name, age, _id 필드를 가져오고($project) age 를 내림차순으로 정렬($sort)한 다음 최대 10개까지 반환($limit)하는 로직이다.
Model.aggregate([
{ $match: { name: 'Junseo' } },
{ $project: { name: 1, age: 1, _id: 0 } },
{ $sort: { age: -1 } },
{ $limit: 10 }
]);
3. find 와 차이점 / 장점
단순 조회인 find 에 비해 aggregate는 더욱 확장된 연산을 지원한다. 대표적으로는 Join, Grouping 이 있다.
3-1. Join
먼저 흔히 알려져있는 find() 의 populate는 Join이 아니다. Join 처럼 보이지만 내부적으로 어플리케이션 레이어에서 두번의 로직을 실행하는 것이다.
하지만 아래 코드와 같이 aggregate 을 사용하면 MongoDB 단에서 한번의 조회를 통해 Join 을 구현할 수 있다.
Order.aggregate([
{
$lookup: {
from: 'users',
localField: 'userId',
foreignField: '_id',
as: 'userInfo'
}
},
{ $unwind: '$userInfo' },
{ $project: { orderNumber: 1, userName: '$userInfo.name' } }
]);
3-2. Grouping
아래 코드와 같이 MongoDB에서 grouping 을 할 수 있다. find 로는 구현이 불가하다.
User.aggregate([
{ $group: { _id: '$age', count: { $sum: 1 } } },
{ $sort: { count: -1 } }
]);
또한 Atlas Search 의 기능을 aggregate을 통해 구현할 수 있다.
아래 코드는 이번에 검색 기능을 구현한 코드의 일부분이다. $search 연산자가 Atlas Search 를 이용하는 연산자이다.
searchPipeline.push(
{
$search: {
index: 'geo',
compound: {
should: keywordScoreQuery,
minimumShouldMatch: 1,
...(geoFilterQuery ? { filter: geoFilterQuery } : {}),
},
},
},
... 중략
4. 단점과 보완 방법
완벽해보이는 메소드지만 단점도 있다.
1. find 에 비해 속도가 느림
여러 연산을 처리하도록 설계되어 있다보니 당연히 find에 비해 절대적인 성능은 좋지않다.
따라서 aggregate를 사용할 땐 Index를 잘 활용하여 성능을 뒷받침해주어야 한다.
(여담으로, Atlas Search 를 사용할 땐 무조건 Search Index 라는 것을 설정해야 한다.)
2. 코드 복잡성 증가
위에 올린 코드들만 봐도 find 에 비해 가독성이 확 떨어진다. 연산자 이름도 직관적이지않다보니 더욱 부각되는 것 같은데, 주석을 잘 활용해야 할 것 같다.
'Backend > Mongoose' 카테고리의 다른 글
| Mongoose Geo-Query / Geo-JSON 사용법 (0) | 2025.06.19 |
|---|