Computer >> 컴퓨터 >  >> 프로그래밍 >> MongoDB

MongoDB에서 날짜별 그룹화(Group By Date)로 중복 날짜 레코드 개수 집계하기

MongoDB에서 중복된 날짜 레코드의 개수를 집계하려면 aggregate() 메서드와 $group 단계를 활용하면 됩니다. 이 글에서는 실제 예제를 통해 날짜별로 문서를 그룹화하고, 각 날짜가 몇 번 등장하는지 확인하는 방법을 단계별로 살펴보겠습니다.

1. 샘플 컬렉션 생성하기

먼저 insertOne() 메서드를 사용해 날짜 데이터(DueDate)를 가진 문서들을 컬렉션에 삽입합니다.

> db.demo160.insertOne({"DueDate":new ISODate()});
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5e357525fdf09dd6d0853a04")
}
> db.demo160.insertOne({"DueDate":new ISODate("2019-01-11")});
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5e357532fdf09dd6d0853a05")
}
> db.demo160.insertOne({"DueDate":new ISODate()});
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5e357534fdf09dd6d0853a06")
}
> db.demo160.insertOne({"DueDate":new ISODate("2019-01-11")});
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5e357538fdf09dd6d0853a07")
}
> db.demo160.insertOne({"DueDate":new ISODate("2020-04-10")});
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5e357542fdf09dd6d0853a08")
}

2. 저장된 문서 확인하기

find() 메서드를 사용하면 컬렉션에 저장된 모든 문서를 조회할 수 있습니다.

> db.demo160.find();

위 명령을 실행하면 다음과 같은 결과가 출력됩니다.

{ "_id" : ObjectId("5e357525fdf09dd6d0853a04"), "DueDate" : ISODate("2020-02-01T12:55:01.983Z") }
{ "_id" : ObjectId("5e357532fdf09dd6d0853a05"), "DueDate" : ISODate("2019-01-11T00:00:00Z") }
{ "_id" : ObjectId("5e357534fdf09dd6d0853a06"), "DueDate" : ISODate("2020-02-01T12:55:16.787Z") }
{ "_id" : ObjectId("5e357538fdf09dd6d0853a07"), "DueDate" : ISODate("2019-01-11T00:00:00Z") }
{ "_id" : ObjectId("5e357542fdf09dd6d0853a08"), "DueDate" : ISODate("2020-04-10T00:00:00Z") }

3. 날짜별 그룹화 및 중복 레코드 집계 쿼리

다음은 MongoDB에서 날짜별로 문서를 그룹화하고 각 날짜의 빈도수를 계산하는 집계 쿼리입니다. 핵심 아이디어는 $dayOfYear$year 연산자를 조합해 고유한 날짜 키를 만들고, 이를 기준으로 그룹화하는 것입니다.

> db.demo160.aggregate([
...    { $group: {
...       _id: {
...          $add: [
...             { $dayOfYear: "$DueDate"},
...             { $multiply:
...             [400, {$year: "$DueDate"}]
...          }
...       ]},
...       Frequency: { $sum: 1 },
...       d: {$min: "$DueDate"}
...    }
... },
... { $sort: {_id: 1} },
... { $limit: 100},
... { $project: { date: "$d", Frequency: 1, _id: 0} }
... ]);

쿼리 동작 원리

  • $dayOfYear: 해당 날짜가 1년 중 몇 번째 날인지 반환합니다.
  • $year: 날짜에서 연도 값을 추출합니다. 여기에 400을 곱하면 서로 다른 연도 간의 키 충돌을 방지할 수 있습니다(1년은 최대 366일이므로).
  • $sum: 1: 같은 날짜 그룹에 속한 문서의 개수를 누적해 빈도수(Frequency)를 계산합니다.
  • $min: "$DueDate": 각 그룹 내 가장 이른 날짜를 대표 날짜(d)로 선택합니다.
  • $sort, $limit, $project: 결과를 오름차순으로 정렬하고, 출력 개수를 제한한 뒤 필요한 필드만 남겨 깔끔한 형태로 변환합니다.

4. 실행 결과

집계 파이프라인을 실행하면 다음과 같이 각 날짜별 중복 레코드 수가 출력됩니다.

{ "Frequency" : 2, "date" : ISODate("2019-01-11T00:00:00Z") }
{ "Frequency" : 2, "date" : ISODate("2020-02-01T12:55:01.983Z") }
{ "Frequency" : 1, "date" : ISODate("2020-04-10T00:00:00Z") }

결과를 보면 2019-01-112020-02-01 날짜에는 각각 2개의 중복 레코드가 있고, 2020-04-10에는 1개의 레코드만 존재함을 알 수 있습니다. 이처럼 aggregate()$group을 조합하면 날짜 기반 중복 데이터 분석을 손쉽게 처리할 수 있습니다.