실제 예제로 익히는 aggregation

이해하기 쉽고, 장황하지 않은 자료를 기반으로 강의를 진행합니다.
잔재미코딩 소식 공유
좀더 제약없이, IT 컨텐츠를 공유하고자, 자체 온라인 사이트와, 다음 두 채널도 오픈하였습니다
응원해주시면, 곧 좋은 컨텐츠를 만들어서 공유하겠습니다
●  잔재미코딩 뉴스레터 오픈 [구독해보기]
●  잔재미코딩 유투브 오픈 [구독해보기]

5. 실제 예제로 익히는 aggregation

5.1. 실제 예제1: 1000만 이상의 state만 가져오기

  • SQL구문으로 작성해보기
    zip 컬렉션 - {'_id': '01001', 'city': 'AGAWAM', 'loc': [-72.622739, 42.070206], 'pop': 15338, 'state': 'MA'}
SQL(zip을 테이블이라고 생각) : SELECT state, SUM(pop) FROM zip GROUP BY state HAVING SUM(pop) > 10000000
  • GROUP BY 는 $group, WHERE$match 를 사용할 수 있음
  • GROUP BY 에 조건을 거는 HAVING 절도 $match 로 사용할 수 있음
In [6]:
result = db.zip.aggregate([
    {'$group' : {'_id' : '$state', 'total_pop' : {'$sum' : '$pop'}}},
    {'$limit': 5}
])
for record in result:
    print(record)
{'_id': 'CA', 'total_pop': 29754890}
{'_id': 'MT', 'total_pop': 798948}
{'_id': 'MS', 'total_pop': 2573216}
{'_id': 'FL', 'total_pop': 12686644}
{'_id': 'AR', 'total_pop': 2350725}
출력 fields
- '_id' : '$field' --> SQL에서 GROUP BY field.
- total_pop : a calculated field that contains the total population of each state.
  - $sum operator : Add the population field (pop) for each state.

SQL과 비교해보자.
- SQL: SELECT state, SUM(pop) FROM zip GROUP BY state  
- mongodb aggregate: db.zip.aggregate([ {'$group' : {'_id' : '$state', 'total_pop' : {'$sum' : '$pop'}}} ])
본 자료와 같이 IT 기술을 잘 정리하여, 온라인 강의로 제공하고 있습니다
체계적으로 전문가 레벨까지 익힐 수 있도록 온라인 강의 로드맵을 제공합니다
In [7]:
# total_pop 만 출력하되 5개만 출력하기
result = db.zip.aggregate([
    {'$group' : {'_id' : '$state', 'total_pop' : {'$sum' : '$pop'} } },
    {'$project' : {'_id' : 0, 'total_pop' : 1} },
    {'$limit' : 5 }
])
for record in result:
    print(record)
{'total_pop': 29754890}
{'total_pop': 798948}
{'total_pop': 2573216}
{'total_pop': 12686644}
{'total_pop': 2350725}
In [8]:
result = db.zip.aggregate([
    {'$match' : {'pop' : {'$gte' : 100000}}},
    {'$limit' : 5 }
])
for record in result:
    print(record)
{'_id': '10021', 'city': 'NEW YORK', 'loc': [-73.958805, 40.768476], 'pop': 106564, 'state': 'NY'}
{'_id': '10025', 'city': 'NEW YORK', 'loc': [-73.968312, 40.797466], 'pop': 100027, 'state': 'NY'}
{'_id': '11226', 'city': 'BROOKLYN', 'loc': [-73.956985, 40.646694], 'pop': 111396, 'state': 'NY'}
{'_id': '60623', 'city': 'CHICAGO', 'loc': [-87.7157, 41.849015], 'pop': 112047, 'state': 'IL'}
출력 fields
- 전체 필드

SQL과 비교해보자.
- SQL: SELECT * FROM zip WHERE pop >= 100000  
- mongodb aggregate: db.zip.aggregate([ {'$match' : {'pop' : {'$gte' : 100000}}} ])
In [9]:
result = db.zip.aggregate([
    {'$group' : {'_id' : '$state', 'total_pop' : {'$sum' : '$pop'}}},
    {'$match' : {'total_pop' : {'$gte' : 10*1000*1000}}}
])
for record in result:
    print(record)
{'_id': 'CA', 'total_pop': 29754890}
{'_id': 'FL', 'total_pop': 12686644}
{'_id': 'PA', 'total_pop': 11881643}
{'_id': 'NY', 'total_pop': 17990402}
{'_id': 'OH', 'total_pop': 10846517}
{'_id': 'IL', 'total_pop': 11427576}
{'_id': 'TX', 'total_pop': 16984601}
- SQL1: SELECT state, SUM(pop) AS total_pop FROM zip GROUP BY state
- SQL2: SELECT * FROM zip WHERE pop >= 100000
- SQL1 + SQL2: SELECT state, SUM(pop) AS total_pop FROM zip HAVING pop >= 10000000

- mongodb aggregate:
result = db.zip.aggregate([
    {'$group' : {'_id' : '$state', 'total_pop' : {'$sum' : '$pop'}}},
    {'$match' : {'total_pop' : {'$gte' : 10*1000*1000}}}
])
본 자료와 같이 IT 기술을 잘 정리하여, 온라인 강의로 제공하고 있습니다
체계적으로 전문가 레벨까지 익힐 수 있도록 온라인 강의 로드맵을 제공합니다
이해하고 실습하기
1000만 이상의 state 의 총 인구를 state_pop 필드명으로 출력하고 _id는 출력하지 않기
In [10]:
result = db.zip.aggregate([
    {'$group' : {'_id' : '$state', 'state_pop' : {'$sum' : '$pop'}}},
    {'$match' : {'state_pop' : {'$gte' : 10*1000*1000}}},
    {'$project' : { '_id' : 0, 'state_pop': 1}}
])
for record in result:
    print(record)
{'state_pop': 29754890}
{'state_pop': 12686644}
{'state_pop': 11881643}
{'state_pop': 17990402}
{'state_pop': 10846517}
{'state_pop': 11427576}
{'state_pop': 16984601}

5.2. 실제 예제2: 1000만 이상의 state만 내림차순 정렬하여 3개만 가져오기

* $limit (LIMIT)

</pre>

  • group : 문자 그대로 grouping의 역할을 함
  • match : 조건에 맞는 documents만 필터링 함
  • sort : 차순에 맞게 정렬
  • limit : 개수 제한

1000만 이상의 state만 내림차순 정렬하기 ($sort)

In [11]:
result = db.zip.aggregate([
             {'$group' : {'_id' : '$state', 'total_pop' : {'$sum' : '$pop'}}}, 
             {'$match' : {'total_pop' : {'$gte' : 10 * 1000 * 1000}}},
             {'$sort' : {'total_pop' : -1}}
])
for record in result:
    print(record)
{'_id': 'CA', 'total_pop': 29754890}
{'_id': 'NY', 'total_pop': 17990402}
{'_id': 'TX', 'total_pop': 16984601}
{'_id': 'FL', 'total_pop': 12686644}
{'_id': 'PA', 'total_pop': 11881643}
{'_id': 'IL', 'total_pop': 11427576}
{'_id': 'OH', 'total_pop': 10846517}
본 자료와 같이 IT 기술을 잘 정리하여, 온라인 강의로 제공하고 있습니다
체계적으로 전문가 레벨까지 익힐 수 있도록 온라인 강의 로드맵을 제공합니다

1000만 이상의 state만 내림차순 정렬하고 5개만 가져오기 ($limit)

In [12]:
result = db.zip.aggregate([
             {'$group' : {'_id' : '$state', 'total_pop' : {'$sum' : '$pop'}}}, 
             {'$match' : {'total_pop' : {'$gte' : 10 * 1000 * 1000}}},
             {'$sort' : {'total_pop' : -1}},
             {'$limit' : 5}
])
for record in result:
    print(record)
{'_id': 'CA', 'total_pop': 29754890}
{'_id': 'NY', 'total_pop': 17990402}
{'_id': 'TX', 'total_pop': 16984601}
{'_id': 'FL', 'total_pop': 12686644}
{'_id': 'PA', 'total_pop': 11881643}

이해하고 실습하기
1000만 이상의 state 의 총 인구를 state_pop 필드명으로 출력하고 _id는 출력하지 않으며, 가장 많은 인구를 가진 3개만 출력하기 </font>

In [14]:
result = db.zip.aggregate([
    {'$group' : {'_id' : '$state', 'state_pop' : {'$sum' : '$pop'}}},
    {'$match' : {'state_pop' : {'$gte' : 10*1000*1000}}},
    {'$sort' : { 'state_pop' : -1 }},
    {'$project' : { '_id' : 0, 'state_pop': 1}},
    {'$limit' : 3}
])
for record in result:
    print(record)
{'state_pop': 29754890}
{'state_pop': 17990402}
{'state_pop': 16984601}