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