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

MongoDB $group과 $facet으로 여러 집계 결과 한 번에 조회하기

여러 개의 집계 결과를 한 번에 얻으려면 MongoDB의 $group 연산자와 $facet 단계를 함께 사용하면 됩니다. 이 글에서는 샘플 데이터를 준비한 뒤, 이름별 점수 합계와 카테고리별 점수 합계를 단 한 번의 쿼리로 동시에 계산하는 방법을 살펴보겠습니다.

샘플 데이터 생성

먼저 demo765 컬렉션을 만들고 세 개의 문서를 차례로 삽입합니다.

> db.demo765.insertOne({
...    Name: "John",
...    Category: "ComputerScience",
...    SubjectName: "MongoDB",
...    Marks: 75
... });
{ "acknowledged" : true, "insertedId" : ObjectId("5eb054525637cd592b2a4b01") }

> db.demo765.insertOne({
...    Name: "John",
...    Category: "ComputerScience",
...    SubjectName: "MySQL",
...    Marks: 85
... });
{ "acknowledged" : true, "insertedId" : ObjectId("5eb054525637cd592b2a4b02") }

> db.demo765.insertOne({
...    Name: "Chris",
...    Category: "10th",
...    SubjectName: "Math",
...    Marks: 98
... });
{ "acknowledged" : true, "insertedId" : ObjectId("5eb054535637cd592b2a4b03") }

저장된 문서 확인하기

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

> db.demo765.find();

실행 결과는 다음과 같습니다.

{ "_id" : ObjectId("5eb054525637cd592b2a4b01"), "Name" : "John", "Category" : "ComputerScience", "SubjectName" : "MongoDB", "Marks" : 75 }
{ "_id" : ObjectId("5eb054525637cd592b2a4b02"), "Name" : "John", "Category" : "ComputerScience", "SubjectName" : "MySQL", "Marks" : 85 }
{ "_id" : ObjectId("5eb054535637cd592b2a4b03"), "Name" : "Chris", "Category" : "10th", "SubjectName" : "Math", "Marks" : 98 }

$group과 $facet으로 다중 집계 실행하기

아래 쿼리는 하나의 집계 파이프라인 안에서 두 가지 기준의 그룹화를 동시에 수행합니다. $facet은 여러 개의 하위 파이프라인을 각각 실행하고 그 결과를 하나의 문서로 묶어 반환하는 단계입니다.

> db.demo765.aggregate([
...    { "$facet": {
...       "ListOfName": [
...          { "$group": {
...             "_id": "$Name",
...             "Marks": { "$sum": "$Marks" }
...          }},
...          { "$project": {
...             "_id": false,
...             "Name": "$_id",
...             "Marks": 1
...          }}
...       ],
...       "ListOfCategory": [
...          { "$group": {
...             "_id": "$Category",
...             "Marks": { "$sum": "$Marks" }
...          }},
...          { "$project": {
...             "_id": false,
...             "Category": "$_id",
...             "Marks": 1
...          }}
...       ]
...    }}
... ]).pretty()

쿼리의 동작 방식을 단계별로 정리하면 다음과 같습니다.

  • ListOfNameName 필드를 기준으로 $group하여 학생별 Marks 합계를 계산합니다.
  • ListOfCategoryCategory 필드를 기준으로 $group하여 카테고리별 Marks 합계를 계산합니다.
  • $project — 그룹 키로 생성된 _id를 제거하고 이를 Name 또는 Category 필드로 되돌려 결과를 읽기 좋게 다듬습니다.

실행 결과는 다음과 같습니다.

{
   "ListOfName" : [
      {
         "Marks" : 98,
         "Name" : "Chris"
      },
      {
         "Marks" : 160,
         "Name" : "John"
      }
   ],
   "ListOfCategory" : [
      {
         "Marks" : 98,
         "Category" : "10th"
      },
      {
         "Marks" : 160,
         "Category" : "ComputerScience"
      }
   ]
}

마무리

$facet$group을 조합하면 컬렉션을 한 번만 스캔하면서도 서로 다른 기준의 집계를 동시에 수행할 수 있습니다. 대시보드나 통계 리포트처럼 여러 지표를 한 번의 요청으로 가져와야 하는 상황에서 특히 유용한 패턴이니 꼭 기억해 두세요.