MongoDB에서 중복된 값이 섞여 있는 문서들 사이에서 최소값과 최대값을 한 번에 구하려면 aggregate() 메서드와 $group 단계를 사용하면 됩니다. 이때 최소값에는 $min, 최대값에는 $max 연산자를 함께 활용합니다.
1. 샘플 데이터 생성
먼저 테스트용 컬렉션을 만들고 문서를 삽입해 보겠습니다. 아래 예제에서는 점수(Score) 필드에 중복된 값(60)이 포함되어 있습니다.
> db.demo167.insertOne({"Score":60});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e3693a79e4f06af551997d1")
}
> db.demo167.insertOne({"Score":80});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e3693ab9e4f06af551997d2")
}
> db.demo167.insertOne({"Score":60});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e3693ad9e4f06af551997d3")
}
> db.demo167.insertOne({"Score":90});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e3693b09e4f06af551997d4")
}
> db.demo167.insertOne({"Score":89});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e3693b69e4f06af551997d5")
}2. 저장된 문서 확인하기
find() 메서드를 사용하면 컬렉션에 저장된 모든 문서를 확인할 수 있습니다.
> db.demo167.find();
위 명령은 다음과 같은 결과를 출력합니다.
{ "_id" : ObjectId("5e3693a79e4f06af551997d1"), "Score" : 60 }
{ "_id" : ObjectId("5e3693ab9e4f06af551997d2"), "Score" : 80 }
{ "_id" : ObjectId("5e3693ad9e4f06af551997d3"), "Score" : 60 }
{ "_id" : ObjectId("5e3693b09e4f06af551997d4"), "Score" : 90 }
{ "_id" : ObjectId("5e3693b69e4f06af551997d5"), "Score" : 89 }3. 최소값과 최대값을 구하는 집계 쿼리
이제 $group 단계에서 _id를 고정값으로 지정해 전체 문서를 하나의 그룹으로 묶고, 각각 $min과 $max로 Score 필드의 최소값과 최대값을 계산합니다.
> var d = [
... {
... "$group": {
... "_id": "id",
... "MinimumValue": { "$min": "$Score" },
... "MaximumValue": { "$max": "$Score" }
... }
... }
... ]
> db.demo167.aggregate(d);실행 결과는 다음과 같습니다.
{ "_id" : "id", "MinimumValue" : 60, "MaximumValue" : 90 }결과 해석
집계 결과에서 MinimumValue는 60으로, 중복 레코드가 있어도 정상적으로 가장 작은 값이 반환된 것을 확인할 수 있습니다. 마찬가지로 MaximumValue에는 90이라는 가장 큰 값이 담겨 있습니다.
이처럼 aggregate()의 $group 단계에서 $min, $max를 조합하면 별도의 정렬(sort)이나 limit 처리 없이도 단 한 번의 파이프라인 실행으로 전체 데이터의 최소값과 최대값을 효율적으로 얻을 수 있습니다.