티스토리 뷰

개인 공부를 위하여 몽고 디비 공식 문서: Aggregation with the Zip Code Data Set 을 한글로 번역한 글입니다.

Aggregation Pipeline: Example with the Zip Code Data set

우편번호 데이터를 이용한 어그리게이션 파이프라인 예시

이 페이지에서는 다음을 다룬다.

  • Data Model / 데이터 모델
  • aggregate() Method / aggregate() 메소드
  • Return States with Populations above 10 Million / 1,000만 명 이상의 인구가 있는 State 반환
  • Return Average City Population by State / State별 평균 도시 인구 반환
  • Return Largest and Smallest Cities by State / State별 가장 크고 작은 도시 반환

이 문서의 예시들은 zipcodes 컬렉션을 사용한다. 이 컬렉션은 media.mongodb.org/zips.json에서 이용 가능하다. mongoimport를 사용하여 당신의 mongod 인스턴스에 이 데이터셋을 로드하라.

 


Data Model / 데이터 모델

zipcodes 컬렉션의 각 도큐먼트는 아래 형식을 갖는다:

{
  "_id": "10280",
  "city": "NEW YORK",
  "state": "NY",
  "pop": 5574,
  "loc": [
    -74.016323,
    40.710537
  ]
}
  • _id 필드: 우편번호 / string
  • city 필드: 도시명. 하나의 도시는 우편번호를 두 개 이상 가질 수 있다.
  • state 필드: State의 2글자 축약
  • pop 필드: 인구
  • loc 필드: 위도 경도 쌍으로 위치 표시

 


aggregate() Method / aggregate() 메소드

다음 모든 예제들은 mongo 셸에서 aggregate() helper를 이용한다.

 

aggregate() 메소드는 도큐먼트들을 어그리게이션된 결과로 처리하기 위하여 어그리게이션 파이프라인을 사용한다. 어그리게이션 파이프라인은 각 스테이지가 파이프라인을 통과할 때 도큐먼트를 처리하는 스테이지로 구성된다. 도큐먼트들은 스테이지들을 차례대로 통과한다.

 

mongo 셸에서 aggregate() 메소드는 aggregate 데이터베이스 명령 주위에 래퍼를 제공한다. 

 


Return States with Populations above 10 Million / 1,000만 명 이상의 인구가 있는 State 반환

다음 어그리게이션 연산은 1,000만 명 이상의 인구가 있는 모든 states를 반환한다.

db.zipcodes.aggregate( [
  { $group: { _id: "$state", totalPop: { $sum: "$pop" } } },
  { $match: { totalPop: { $gte: 10*1000*1000 } } }
] )

이 예시에서, 어그리게이션 파이프라인$group 스테이지 다음에 $match 스테이지로 구성된다.

  • $group 스테이지는 zipcode 컬렉션의 도큐먼트를 state 필드로 그룹화하고, 각 state의 totalPop 필드를 계산하여 각각의 유니크한 state의 도큐먼트를 출력한다. 새로운 state당 도큐먼트들은 _id 필드와 totalPop 필드의 두 가지 필드를 갖는다. _id 필드는 state값을 갖는다. (예를 들어 group by 필드) totalPop 필드는 각 state의 총 인구를 갖는 계산된 필드이다. 값을 계산하기 위해, $group은 각 state의 인구 필드(pop)를 더하기 위하여 $sum 연산자를 사용한다. $group 스테이지 후, 파이프라인의 도큐먼트들은 다음과 같다:
{
  "_id": "AK",
  "totalPop": 550043
}

 

  • $match 스테이지는 이 그룹화된 도큐먼트들을 totalPop 값이 1,000만 이상인 도큐먼트만 출력하도록 필터링한다. $match 스테이지는 일치하는 도큐먼트를 변경하지 않고 수정되지 않은 상태로 출력한다.

이 어그리게이션 연산과 동일한 SQL은 다음과 같다:

SELECT state, SUM(pop) AS totalPop
FROM zipcodes
GROUP BY state
HAVING totalPop >= (10*1000*1000)

Return Average City Population by State / State별 평균 도시 인구 반환

다음 어그리게이션 연산은 각 state의 평균 인구를 반환한다.:

db.zipcodes.aggregate( [
  { $group: { _id: { state: "$state", city: "$city" }, pop: { $sum: "$pop" } } },
  { $group: { _id: "$_id.state", avgCityPop: { $avg: "$pop" } } }
] )

이 예시에서, 어그리게이션 파이프라인은 $group 스테이지 다음에 또 다른 $group 스테이지로 구성된다.

  • 첫번째 $group 스테이지는 city와 state를 조합하여 도큐먼트를 그룹화하고, $sum 식을 이용하여 각 조합에 대하여 인구를 계산하고, 각 city와 state의 조합에 대한 도큐먼트를 출력한다. 파이프라인의 이 스테이지 후의 도큐먼트는 다음과 같다.:
{
  "_id" : {
    "state" : "CO",
    "city" : "EDGEWATER"
  },
  "pop": 13154
}
  • 두번째 $group 스테이지는 _id.state 필드로 파이프라인의 도큐먼트를 그룹화하고 (_id 도큐먼트 내부의 state 필드), $avg 식을 이용하여 각 state의 평균 도시 인구(avgCityPop)를 계산하고, 각 state에 대한 도큐먼트를 출력한다.

이 어그리게이션 연산의 결과 도큐먼트는 다음과 같은 형식이다.:

{
  "_id" : "MN",
  "avgCityPop" : 5335
}

Return Largest and Smallest Cities by State / State별 가장 크고 작은 도시 반환

다음 어그리게이션 연산은 각 state별 인구가 가장 작고 큰 도시를 반환한다.:

db.zipcodes.aggregate( [
  { $group:
    {
      _id: { state: "$state", city: "$city" },
      pop: { $sum: "$pop" }
    }
  },
  { $sort: { pop: 1 } },
  { $group:
    {
      _id: "$_id.state",
      biggestCity: { $last: "$_id.city" },
      biggestPop: { $last: "$pop" },
      smallestCity: { $first: "$_id.city" },
      smallestPop: { $first: "$pop" }
    }
  },

  // the following $project is optional, and
  // modifies the output format.

  { $project:
    { _id: 0,
      state: "$_id",
      biggestCity: { name: "$biggestCity", pop: "$biggestPop" },
      smallestCity: { name: "$smallestCity", pop: "$smallestPop" }
    }
  }
] )

이 예시에서, 어그리게이션 파이프라인$group 스테이지와 $sort 스테이지, 또 다른 $group 스테이지, 그리고 $project 스테이지로 구성된다.:

  • 첫번째 $group 스테이지는 citystate의 조합으로 도큐먼트를 그룹화하고, 각 조합에 대해 pop 값의 sum을 계산하고, 각 citystate 조합에 대한 도큐먼트를 출력한다. 파이프라인의 이 스테이지에서, 도큐먼트는 다음 형식과 같다.:
{
  "_id": {
    "state": "CO",
    "city": "EDGEWATER"
  },
  "pop": 13154
}
  • $sort 스테이지는 파이프라인의 도큐먼트를 pop 필드값으로 최소에서 최대까지 정렬한다. (increasing order) 이 연산은 도큐먼트를 변경하지 않는다.
  • 다음 $group 스테이지는 정렬된 도큐먼트를 _id.state 필드로 그룹화하고, (_id 도큐먼트 내부의 state 필드) 각 state에 대하여 도큐먼트를 출력한다. 또한 다음 4가지 필드를 각 state에 대하여 계산한다. $last 식을 이용하여, $group 연산자는 가장 큰 인구를 갖는 도시와 그 인구를 저장하는 biggestCitybiggestPop 필드를 생성한다. $first 식을 이용하여, $group 연산자는 가장 작은 인구를 갖는 도시와 그 인구를 저장하는 smallestCitysmallestPop 필드를 생성한다. 파이프라인의 이 스테이지에서 도큐먼트들은 다음 형식과 같다.:
{
  "_id" : "WA",
  "biggestCity" : "SEATTLE",
  "biggestPop" : 520096,
  "smallestCity" : "BENGE",
  "smallestPop" : 2
}
  • 마지막 $project 스테이지는 _id 필드를 state로 이름을 바꾸고 biggestCity, biggestPop, smallestCity, smallestPopbiggestCitysmallestCity의 내장 도큐먼트로 이동시킨다.

이 어그리게이션 연산의 출력 도큐먼트는 다음 형식과 같다.:

{
  "state" : "RI",
  "biggestCity" : {
    "name" : "CRANSTON",
    "pop" : 176404
  },
  "smallestCity" : {
    "name" : "CLAYVILLE",
    "pop" : 45
  }
}

 

728x90
댓글