개발관련/MongoDB
2015. 11. 20. 13:39
aggregation은 '집합' 이란 뜻이다. 고로, 특정 데이터의 통계를 뽑을 때 많이 쓰인다. mapreduce는 통계의 추이를 뽑고 싶을 때 사용되며 aggregation은 양이 적고, 휘발성인 통계를 뽑을 때 사용하면 좋다.
사용법은 공식 싸이트 https://docs.mongodb.org/manual/reference/operator/aggregation/ 이넘을 참고하자. 또는 http://hongtaey.tistory.com/57 이 분 역시 나름 정리를 잘하신듯.. 보인다.
그럼 한번 해보자.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | use dbname db.users.find(); //result /* 1 */ { "_id" : "564c3240e5aa2a5f7c7bd7f5", "index" : 0, "isActive" : false, "age" : 30, "eyeColor" : "green", "name" : "Rodgers Grant", "gender" : "male", "company" : "VERTON", "email" : "rodgersgrant@verton.com" } ........................생략........................ | cs |
먼저 aggregation을 할 db로 변경 후 결과를 보자. 위의 결과는 users의 collections의 결과이다.
그럼 eyeColor가 'green' 사람을 찾아보자.
1 2 3 4 5 6 7 8 9 | //aggregation db.users.aggregate( //stage 별로 나뉘며 앞에서 처리 된걸 가지고 다음 stage로 전달 [{ $match : { "eyeColor" :"green" } }] ); | cs |
aggregation이라는 함수로 내부에 array를 가지며 이를 다시 object 형태를 가진다. 여기서 중요한 것은 각 object의 순서 마다 stage 라 칭하며 , pipeline 형태로 다음 state로 전달하게 된다.
위의 결과는 다음과 같다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | { "result" : [ { "_id" : "564d1acb42b552b7a4e93ff4", "index" : 19347, "isActive" : true, "age" : 30, "eyeColor" : "green", "name" : "Spencer Brady", "gender" : "male", "company" : "KIDSTOCK", "email" : "spencerbrady@kidstock.com" }, { "_id" : "564c3240e5aa2a5f7c7bd7f5", "index" : 0, "isActive" : false, "age" : 30, "eyeColor" : "green", "name" : "Rodgers Grant", "gender" : "male", "company" : "VERTON", "email" : "rodgersgrant@verton.com" } ............................생략.............................................. | cs |
와 잘나온다. 그리고 쉽다!!!!! 흠.. 그럼 stage라고 하는넘을 해보자.
이제 위의 결과를 가지고 응용하자. "눈이 녹색이고, 나이가 30보다 많은 사람"를 찾아보자.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | db.users.aggregate([ //stage 별로 나뉘며 앞에서 처리 된걸 가지고 다음 stage로 전달 //stage 1 { $match : { "eyeColor" :"green" } }, //stage 2 { $match :{ "age" : { $gt : 30 } } } ]); | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | "result" : [ { "_id" : "564d1acb42b552b7a4e93ff4", "index" : 19347, "isActive" : true, "age" : 30, "eyeColor" : "green", "name" : "Spencer Brady", "gender" : "male", "company" : "KIDSTOCK", "email" : "spencerbrady@kidstock.com" }, { "_id" : "564c3240e5aa2a5f7c7bd7f5", "index" : 0, "isActive" : false, "age" : 30, "eyeColor" : "green", "name" : "Rodgers Grant", "gender" : "male", "company" : "VERTON", "email" : "rodgersgrant@verton.com" }, ..........................생략.................................. | cs |
잘나온다... 흠. 근데 먼가 예제로서는 부족하다... stage라는 넘을 잘 모르겠다.
쿼리를 좀 바꿔보자. $match 말고 $group도 사용해보자. "index가 10000 이상이며, eyeColor 별 사람은 몇명인지"를 찾아보자.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | db.users.aggregate([ //stage 별로 나뉘며 앞에서 처리 된걸 가지고 다음 stage로 전달 //stage 1 { $match : { "index" :{ $gte: 10000 } } }, { $group:{ "_id" : "$eyeColor", "sum" : { $sum : 1 } } } ]); | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | /* 1 */ { "result" : [ { "_id" : "brown", "sum" : 3296.0000000000000000 }, { "_id" : "blue", "sum" : 3362.0000000000000000 }, { "_id" : "green", "sum" : 3342.0000000000000000 } ], "ok" : 1.0000000000000000, "$gleStats" : { "lastOpTime" : Timestamp(1448006114, 21), "electionId" : ObjectId("564d825928cf905edab537fb") } } | cs |
흠 $sum이라는 함수를 써서 각 숫자의 카운트를 계산후 나온 결과다. 여기서 중요한 것은 $group은 필히 _id 라는 group의 id가 필히 존재해야 한다. 예상대로 전체 10000명 중에 값이 group별로 묶여서 나왔다. 그런데 아직도 stage를 설명 하기엔 무언가 부족하다.
나머진 다음 페이지에서.