개발관련/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(144800611421),
        "electionId" : ObjectId("564d825928cf905edab537fb")
    }
}
cs

흠 $sum이라는 함수를 써서 각 숫자의 카운트를 계산후 나온 결과다. 여기서 중요한 것은 $group은 필히 _id 라는 group의 id가 필히 존재해야 한다. 예상대로 전체 10000명 중에 값이 group별로 묶여서 나왔다. 그런데 아직도 stage를 설명 하기엔 무언가 부족하다. 

나머진 다음 페이지에서. 


posted by 제스트
: