MongoDB에서 aggregate() 메서드를 사용하면 집계 파이프라인을 통해 다양한 통계 값을 계산할 수 있습니다. 이 글에서는 $avg 연산자가 어떤 경우 -Infinity(음의 무한대)를 결과로 반환하는지 실제 예제를 통해 살펴보겠습니다.
1. 테스트용 컬렉션 생성
먼저 -Infinity 값을 포함한 문서들을 담고 있는 컬렉션을 생성해 보겠습니다.
> db.demo5.insertOne({ "_id" : 100, "seq" : 10, "Value" : -Infinity });
{ "acknowledged" : true, "insertedId" : 100 }
> db.demo5.insertOne({ "_id" : 101, "seq" : 10, "Value" : 50 });
{ "acknowledged" : true, "insertedId" : 101 }
> db.demo5.insertOne({ "_id" : 102, "seq" : 20, "Value" : 60 });
{ "acknowledged" : true, "insertedId" : 102 }
> db.demo5.insertOne({ "_id" : 103, "seq" : 20, "Value" : 50 });
{ "acknowledged" : true, "insertedId" : 103 }총 4개의 문서를 삽입했습니다. 여기서 주목할 점은 _id: 100 문서의 Value 필드가 -Infinity라는 것입니다.
2. find()로 전체 문서 확인하기
find() 메서드를 사용하여 컬렉션에 저장된 모든 문서를 조회해 보겠습니다.
> db.demo5.find();
위 쿼리를 실행하면 다음과 같은 결과가 출력됩니다.
{ "_id" : 100, "seq" : 10, "Value" : -Infinity }
{ "_id" : 101, "seq" : 10, "Value" : 50 }
{ "_id" : 102, "seq" : 20, "Value" : 60 }
{ "_id" : 103, "seq" : 20, "Value" : 50 }3. aggregate()로 $avg 계산하기
이제 집계 쿼리에서 $avg 연산자를 사용하여 seq 필드 기준으로 그룹화한 뒤 각 그룹의 평균값을 계산해 보겠습니다.
> db.demo5.aggregate([{$group:{"_id":"$seq", "average" : {$avg : "$Value"}}}] );실행 결과는 다음과 같습니다.
{ "_id" : 20, "average" : 55 }
{ "_id" : 10, "average" : -Infinity }결과 분석
출력 결과를 보면 흥미로운 차이를 발견할 수 있습니다.
- seq가 20인 그룹: 값이 60과 50이므로 평균은 정상적으로 55가 계산됩니다.
- seq가 10인 그룹: 값이 -Infinity와 50이므로 평균은 -Infinity가 됩니다.
그 이유는 MongoDB에서 -Infinity도 하나의 유효한 숫자(double 타입)로 취급되기 때문입니다. 따라서 산술 연산에 그대로 포함되며, 음의 무한대가 포함된 평균 계산은 수학적으로 항상 -Infinity가 됩니다. 즉, (-Infinity + 50) / 2 = -Infinity인 것이죠.
따라서 실무에서는 데이터에 무한대 값이 섞여 들어오지 않도록 입력 단계에서 검증하거나, 집계 전에 $match 등으로 비정상적인 값을 필터링하는 것이 좋습니다.