10Gen에서 제공하는 Aggregation Framework에 대한 동영상 소개 예제를 실습해 본다
1. 준비
- 10Gen 예제
- http://media.mongodb.org/zips.json 데이터를 mongoimport 명령을 이용하여 넣기
// zip.json 예제 mongoimport
$ mongoimport --db bigdata --collection zipcodes --file zip.json
connected to: 127.0.0.1
Sat Aug 3 14:55:27.002 Progress: 1919717/2871006 66%
Sat Aug 3 14:55:27.002 19700 6566/second
Sat Aug 3 14:55:28.258 check 9 29470
Sat Aug 3 14:55:28.259 imported 29470 objects
// mongo shell
> use bigdata
switched to db bigdata
> show collections
system.indexes
zipcodes
2. 간단 수행
- $group -> $match로 pipeline stream 처리
- aggregate 메소드에 {} 객체를 넣고 콤마(,) 로 구분하면 왼쪽-> 오른쪽으로 pipeline 됨
db.zipcodes.aggregate(
{ $group :
{ _id : "$state",
totalPop : { $sum : "$pop" } }
},
{ $match :
{totalPop : { $gte : 10*1000*1000 } }
} );
3. 동영상 따라쟁이
- 샘플 수행 순서 : 일반 operator -find()같은- 와 aggregation framework operator 비교 수행
- $match == find와 같은 결과 그러나 다른 페러다임에서 처리된다는게 함정!
> db.zipcodes.aggregate({$match: {state:'NY', pop: {$gt:110000}}});
{
"result" : [
{
"city" : "BROOKLYN",
"loc" : [
-73.956985,
40.646694
],
"pop" : 111396,
"state" : "NY",
"_id" : "11226"
}
],
"ok" : 1
}
- $match 후에 pipeline을 통하여 $sort 하기 : 단지 콤마(,)로 구분하면 된다
> db.zipcodes.aggregate({$match: {state:'NY'}}, {$sort: {pop:-1}});
- $match | $sort | $limit | $skip pipeline stream 처리
> db.zipcodes.aggregate({$match: {state:'NY'}}, {$sort: {pop:-1}}, {$limit:5}, {$skip: 2});
{
"result" : [
{
"city" : "NEW YORK",
"loc" : [
-73.968312,
40.797466
],
"pop" : 100027,
"state" : "NY",
"_id" : "10025"
},
{
"city" : "JACKSON HEIGHTS",
"loc" : [
-73.878551,
40.740388
],
"pop" : 88241,
"state" : "NY",
"_id" : "11373"
},
{
"city" : "BROOKLYN",
"loc" : [
-73.914483,
40.662474
],
"pop" : 87079,
"state" : "NY",
"_id" : "11212"
}
],
"ok" : 1
}
- 데이터에 $ 부호 사용하기 : 기존 document에는 population 필드가 존재하지 않는다
> db.zipcodes.aggregate({$limit:1}, {$project: {city:1, state:1, pop:1, population:'$pop'}});
{
"result" : [
{
"city" : "ACMAR",
"pop" : 6055,
"state" : "AL",
"_id" : "35004",
"population" : 6055
}
],
"ok" : 1
}
$project가 하는 일은 무엇이 있을까?
- 필드 넣기 : Include fields from the original document.
- 계산된 필드 삽입 : Insert computed fields.
- 필드 이름 변경 : Rename fields.
- 서브도큐멘트에 대한 생성과 조작 : Create and populate fields that hold sub-documents.
- 데이터에 $를 사용해 연산하여 결과를 얻기
> db.zipcodes.aggregate({$limit:1}, {$project: {city:1, state:1, pop:1, population:'$pop', popSquared: {$multiply: ['$pop', '$pop']}} });
{
"result" : [
{
"city" : "ACMAR",
"pop" : 6055,
"state" : "AL",
"_id" : "35004",
"population" : 6055,
"popSquared" : 36663025
}
],
"ok" : 1
}
>
> 6055*6055
36663025
- 기존 필드에 sub document 넣기 . 과 ' ' 사용한다
> db.zipcodes.aggregate({$limit:1}, {$project: {city:1, state:1, population:'$pop', 'pop.Squared': {$multiply: ['$pop', '$pop']}} });
{
"result" : [
{
"city" : "ACMAR",
"pop" : {
"Squared" : 36663025
},
"state" : "AL",
"_id" : "35004",
"population" : 6055
}
],
"ok" : 1
}
- pipeline 해보자 : $group -> $sort -> $limit
> db.zipcodes.aggregate( {$group: {_id: '$state', pop: {$sum: '$pop'}}}, {$sort: {pop:-1}}, {$limit:3});
{
"result" : [
{
"_id" : "CA",
"pop" : 29760021
},
{
"_id" : "NY",
"pop" : 17990455
},
{
"_id" : "TX",
"pop" : 16986510
}
],
"ok" : 1
}
// 하나의 document마다 모든 city가 다 포함되어 결과 검출됨 (실습해 보삼^^)
> db.zipcodes.aggregate( {$group: {_id: '$state', pop: {$sum: '$pop'}, cities:{$addToSet: '$city'}}}, {$sort: {pop:-1}}, {$limit:3});
- _id를 조합한 형태로 Pipeline 해보기 : $group -> $sort -> $limit
> db.zipcodes.aggregate(
{$group:
{
_id: {city: '$city', state: '$state'},
pop: {$sum: '$pop'},
avgPop: {$avg: '$pop'}
}
},
{$sort: {pop: -1}},
{$limit: 1}
)
// 결과
{
"result" : [
{
"_id" : {
"city" : "CHICAGO",
"state" : "IL"
},
"pop" : 2452177,
"avgPop" : 52173.97872340425
}
],
"ok" : 1
}
<참조>
- 예제 json 파일
'MongoDB > MapReduce' 카테고리의 다른 글
[MongoDB] Aggregation Framework 이해하기 (0) | 2013.08.03 |
---|---|
[MongoDB] GridFS 사용하기 (0) | 2013.02.23 |
[MongoDB] GridFS 개념잡기 (0) | 2013.02.23 |