MongoDB의 집계 파이프라인(aggregation pipeline)은 여러 개의 단계(stage)로 구성됩니다. 문서가 파이프라인을 통과하는 동안 각 단계를 거치며 순차적으로 변환되기 때문에, 데이터를 유연하게 가공하고 필터링할 수 있습니다.
이 글에서는 집계 파이프라인을 활용해 MongoDB에서 조건에 맞는 레코드를 가져오는 방법을 예제와 함께 살펴보겠습니다.
1. 샘플 컬렉션 생성
먼저 예제에서 사용할 문서들을 포함하는 컬렉션을 생성합니다.
> db.demo218.insertOne({"Name":"Chris","Branch":"CS",Marks:[65,78,36,90]});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e3e5f4903d395bdc2134712")
}
> db.demo218.insertOne({"Name":"David","Branch":"ME",Marks:[56,45,42,51]});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e3e5f6203d395bdc2134713")
}
> db.demo218.insertOne({"Name":"Chris","Branch":"CS",Marks:[78,65,89]});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e3e5f6c03d395bdc2134714")
}
2. 전체 문서 확인
find() 메서드를 사용하면 컬렉션에 저장된 모든 문서를 조회할 수 있습니다.
> db.demo218.find();
위 명령을 실행하면 다음과 같은 결과가 출력됩니다.
{ "_id" : ObjectId("5e3e5f4903d395bdc2134712"), "Name" : "Chris", "Branch" : "CS", "Marks" : [ 65, 78, 36, 90 ] }
{ "_id" : ObjectId("5e3e5f6203d395bdc2134713"), "Name" : "David", "Branch" : "ME", "Marks" : [ 56, 45, 42, 51 ] }
{ "_id" : ObjectId("5e3e5f6c03d395bdc2134714"), "Name" : "Chris", "Branch" : "CS", "Marks" : [ 78, 65, 89 ] }
3. 집계 파이프라인 쿼리 실행
다음은 집계 파이프라인을 사용한 쿼리입니다. 먼저 $unwind 단계에서 Marks 배열을 개별 요소로 분리하고, $match 단계에서 CS 학과 학생 중 점수가 88보다 큰 문서만 걸러냅니다. 마지막으로 $group 단계에서 문서 ID별로 그룹화한 뒤 $first 연산자를 사용해 각 문서의 첫 번째 일치 값을 반환합니다.
> db.demo218.aggregate([
... { "$unwind": "$Marks" },
... { "$match":
... {
... "Branch": "CS",
... "Marks": { "$gt": 88 }
... }
... },
... { "$group":
... {
... "_id": "$_id",
... "Branch": { "$first": "$Branch" },
... "Marks": { "$first": "$Marks" }
... }
... }
...])
실행 결과는 다음과 같습니다. CS 학과 학생의 문서 중 88점을 초과하는 점수(89점, 90점)를 가진 두 건이 반환된 것을 확인할 수 있습니다.
{ "_id" : ObjectId("5e3e5f6c03d395bdc2134714"), "Branch" : "CS", "Marks" : 89 }
{ "_id" : ObjectId("5e3e5f4903d395bdc2134712"), "Branch" : "CS", "Marks" : 90 }