MongoDB 집계와 프로젝션이란?
MongoDB에서 원하는 필드만 선택적으로 반환받으려면 aggregate() 메서드와 함께 $project 연산자를 사용하면 됩니다. 집계 파이프라인에서 $project 단계는 요청된 필드만 담고 있는 문서를 다음 단계로 전달하는 역할을 합니다.
샘플 컬렉션 생성하기
먼저 실습에 사용할 문서가 포함된 컬렉션을 생성해 보겠습니다.
> db.demo762.insertOne({
... "_id" : {
... "userId" : 101,
... "userName" : "Chris"
... },
... "countryName" : "US",
... "details" : [
... {
... "Name" : "Robert",
... "DueDate" : "2020-04-10"
... },
... {
... "Name" : "Robert",
... "DueDate" : "2020-04-09"
... },
... {
... "Name" : "Robert",
... "DueDate" : "2020-03-06"
... }
... ]
... });
{
"acknowledged" : true,
"insertedId" : {
"userId" : 101,
"userName" : "Chris"
}
}find() 메서드로 전체 문서 확인하기
find() 메서드를 사용하면 컬렉션에 저장된 모든 문서를 화면에 표시할 수 있습니다.
> db.demo762.find();
위 쿼리를 실행하면 다음과 같은 결과가 출력됩니다.
{ "_id" : { "userId" : 101, "userName" : "Chris" }, "countryName" : "US", "details" : [ { "Name" : "Robert", "DueDate" : "2020-04-10" }, { "Name" : "Robert", "DueDate" : "2020-04-09" }, { "Name" : "Robert", "DueDate" : "2020-03-06" } ] }집계 파이프라인으로 프로젝션 수행하기
다음은 MongoDB에서 집계와 프로젝션을 함께 사용하는 쿼리입니다.
> db.demo762.aggregate([
... { "$match": {
... "_id": { "$eq": { userId:101, userName:"Chris" }}
... }},
... { "$unwind": "$details" },
... { "$sort": { "details.DueDate": 1 }},
... { "$group": {
... "_id": "$_id",
... "details": { "$push": "$details" },
... "countryName": { "$first": "$countryName" }
... }},
... { "$project": { "details": { "$slice": ["$details", 2] }, "countryName": 1 }}
... ]).pretty();
이 파이프라인의 각 단계는 다음과 같이 동작합니다.
- $match — userId가 101이고 userName이 "Chris"인 문서만 필터링합니다.
- $unwind — details 배열을 개별 문서 단위로 분해합니다.
- $sort — DueDate 값을 기준으로 오름차순 정렬합니다.
- $group — 원래의 _id를 기준으로 문서를 다시 묶고, details를 배열 형태로 재구성합니다.
- $project — $slice 연산자를 사용해 details 배열에서 처음 2개 요소만 남기고, countryName 필드도 함께 포함시킵니다.
최종 실행 결과
위 집계 쿼리를 실행하면 다음과 같은 출력이 생성됩니다.
{
"_id" : {
"userId" : 101,
"userName" : "Chris"
},
"countryName" : "US",
"details" : [
{
"Name" : "Robert",
"DueDate" : "2020-03-06"
},
{
"Name" : "Robert",
"DueDate" : "2020-04-09"
}
]
}이처럼 $match, $unwind, $sort, $group, $project 단계를 조합하면 배열 내부의 데이터를 원하는 순서대로 정렬한 뒤, 필요한 개수만큼 잘라내어 깔끔한 형태의 결과를 얻을 수 있습니다.