티스토리 뷰
개인 공부를 위하여 몽고 디비 공식 문서: 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 스테이지는 city와 state의 조합으로 도큐먼트를 그룹화하고, 각 조합에 대해 pop 값의 sum을 계산하고, 각 city와 state 조합에 대한 도큐먼트를 출력한다. 파이프라인의 이 스테이지에서, 도큐먼트는 다음 형식과 같다.:
{
"_id": {
"state": "CO",
"city": "EDGEWATER"
},
"pop": 13154
}
- $sort 스테이지는 파이프라인의 도큐먼트를 pop 필드값으로 최소에서 최대까지 정렬한다. (increasing order) 이 연산은 도큐먼트를 변경하지 않는다.
- 다음 $group 스테이지는 정렬된 도큐먼트를 _id.state 필드로 그룹화하고, (_id 도큐먼트 내부의 state 필드) 각 state에 대하여 도큐먼트를 출력한다. 또한 다음 4가지 필드를 각 state에 대하여 계산한다. $last 식을 이용하여, $group 연산자는 가장 큰 인구를 갖는 도시와 그 인구를 저장하는 biggestCity와 biggestPop 필드를 생성한다. $first 식을 이용하여, $group 연산자는 가장 작은 인구를 갖는 도시와 그 인구를 저장하는 smallestCity와 smallestPop 필드를 생성한다. 파이프라인의 이 스테이지에서 도큐먼트들은 다음 형식과 같다.:
{
"_id" : "WA",
"biggestCity" : "SEATTLE",
"biggestPop" : 520096,
"smallestCity" : "BENGE",
"smallestPop" : 2
}
- 마지막 $project 스테이지는 _id 필드를 state로 이름을 바꾸고 biggestCity, biggestPop, smallestCity, smallestPop을 biggestCity와 smallestCity의 내장 도큐먼트로 이동시킨다.
이 어그리게이션 연산의 출력 도큐먼트는 다음 형식과 같다.:
{
"state" : "RI",
"biggestCity" : {
"name" : "CRANSTON",
"pop" : 176404
},
"smallestCity" : {
"name" : "CLAYVILLE",
"pop" : 45
}
}
'dev > mongodb' 카테고리의 다른 글
MacOSX Catalina - mongod /data/db not found 에러 (1) | 2020.10.01 |
---|---|
[번역] MongoDB Aggregation / 어그리게이션, 집합, 집계 (0) | 2019.10.03 |
[번역] MongoDB Delete Documents / 도큐먼트 삭제 (0) | 2019.09.14 |
[번역] MongoDB Update Documents / 도큐먼트 업데이트 (0) | 2019.09.14 |
[번역] MongoDB Query Documents / 도큐먼트 쿼리 (0) | 2019.09.14 |