MongoDB에서 집계(aggregation)를 수행하려면 aggregate() 메서드를 사용합니다. 배열로 저장된 중첩 문서의 날짜를 그룹화하려면 먼저 $unwind로 배열을 분해한 후, $group 연산자로 날짜별 개수를 집계할 수 있습니다.
샘플 컬렉션 생성하기
먼저 배송 정보(shippingdetails) 배열을 포함하는 문서로 컬렉션을 생성해 보겠습니다.
> db.demo717.insertOne(
... {
... "shippingdetails":
... [
... {
... duedate:"2020-04-29 22:33:04",
... },
... {
... duedate:"2020-03-29 22:33:04",
... },
... {
... duedate:"2020-04-29 22:33:04",
... },
... {
... duedate:"2020-01-29 22:33:04",
... }
... ]
... }
... );
{
"acknowledged" : true,
"insertedId" : ObjectId("5ea9b3cd85324c2c98cc4c30")
}저장된 문서 확인하기
find() 메서드를 사용해 컬렉션의 모든 문서를 조회합니다.
> db.demo717.find().pretty();
위 쿼리는 다음과 같은 결과를 출력합니다.
{
"_id" : ObjectId("5ea9b3cd85324c2c98cc4c30"),
"shippingdetails" : [
{
"duedate" : "2020-04-29 22:33:04"
},
{
"duedate" : "2020-03-29 22:33:04"
},
{
"duedate" : "2020-04-29 22:33:04"
},
{
"duedate" : "2020-01-29 22:33:04"
}
]
}날짜별 그룹화 집계 쿼리 작성하기
중첩 문서(중첩 객체) 내의 날짜를 그룹화하려면 다음과 같이 집계 파이프라인을 구성합니다. 핵심은 두 단계로 이루어집니다.
- $unwind: shippingdetails 배열의 각 요소를 개별 문서로 분해합니다.
- $group: 분해된 문서들을 duedate 값 기준으로 묶고,
$sum: 1로 각 날짜가 등장한 횟수를 계산합니다.
> db.demo717.aggregate(
... {
... $unwind:"$shippingdetails"},
... {
... $group: {
... _id: "$shippingdetails.duedate",
... count: {
... $sum: 1
... }
... }
... }
... )집계 결과 확인하기
위 집계 쿼리를 실행하면 각 마감일(duedate)별로 문서가 몇 개씩 존재하는지 확인할 수 있습니다.
{ "_id" : "2020-01-29 22:33:04", "count" : 1 }
{ "_id" : "2020-03-29 22:33:04", "count" : 1 }
{ "_id" : "2020-04-29 22:33:04", "count" : 2 }결과를 보면 '2020-04-29' 날짜는 2번 등록되어 count가 2로 집계된 것을 알 수 있습니다. 이처럼 $unwind와 $group을 조합하면 배열 형태의 중첩 문서 안에 있는 데이터도 손쉽게 그룹화하여 통계를 낼 수 있습니다.