개발관련/MongoDB 2015. 11. 19. 11:27

몽고 db는 아래 그림과 같은 모양으로 구성된다. 

 


(출처는 http://mobicon.tistory.com/307 이분 블로그는 볼게 많아요.) 


설명을 하자면 아마도 클라우드 환경을 지원하는 대부분의 것들이 mongodb와 유사할 것이다. (solr와 es를 좀 틀리다... =-=;;;) 

먼저 cloud는 두가지 말들이 많이 나온다. shard(파편)와 replica(복제) 이 두말이 가장 먼저 나온다. 몽고 db의 shard는 위에 그림과 같이 몽고db의 물리적 서버를 여러개 합쳐놓은 논리적 단위이다. 그럼 전체 데이터를 봤을때 샤드라고 하는 논리적 단위는 일부 만을 가지게 되고 이들이 합쳐져서 전체 데이타를 이룬다. 


 물리적 서버는 다시 노드 또는 데이터 서버 라고 칭하며, 저 노드들간의 여러개를 replicaset 이라는 이름으로 다시 집합을 이룬다. 결론은 replicaset은 흔히 말하는 replica가 된다.  replica는 들어온 데이타들을 상호간에 복제를 하게 된다. 


그럼 mongos라는 넘을 무얼까? 이넘은 클러스터 서버라는 넘이다. 유저가 쿼리를 전송을 하면 클러스터 서버는 데이터를 저장하지 않고 일종의 queue역활을 해준다. 어느 데이터를 누구한테 전할지 이러한 역활을 한다. 오른쪽 위에 보면 config servers 라는 넘이 있는데 이넘은 모든 쿼리를 저장하며 백업등을 관리한다. 이 역시 장애가 발생할 수 있으므로 여러개를 권장한다. 




posted by 제스트
:
개발관련/MongoDB 2015. 11. 17. 11:51
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
//sort 
//asc     
db.crudtest.find(
    {
        
    }
    
).sort(
    {
        "name" : 1
    }
);      
    
//desc     
db.crudtest.find(
    {
        
    }
    
).sort(
    {
        "name" : -1
    }
);          
 
cs

sort는 sort라는 내부함수로 쓰며 1, -1로 오름 차순과 내림차순을 정한다. 


다음은 다량의 데이터를 넣는 bulk 또는 fetch 또는 batch 다. (용어는 =_=; 쓰기나름. )


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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
 
db.users.insert(
    [
  {
    "_id""56497019adbf20c07138d982",
    "index"0,
    "isActive"false,
    "age"24,
    "eyeColor""blue",
    "name""Moon Robles",
    "gender""male",
    "company""MANTRIX",
    "email""moonrobles@mantrix.com"
  },
  {
    "_id""56497019be3cc168feb7b889",
    "index"1,
    "isActive"true,
    "age"32,
    "eyeColor""blue",
    "name""Annabelle Bass",
    "gender""female",
    "company""FOSSIEL",
    "email""annabellebass@fossiel.com"
  },
////////////////////생략/////////////////////////////////
{
    "_id""564970199f18e80dce7f2fed",
    "index"99,
    "isActive"false,
    "age"32,
    "eyeColor""brown",
    "name""Richardson Hansen",
    "gender""male",
    "company""AQUASURE",
    "email""richardsonhansen@aquasure.com"
  }
]
);
cs

insert문에 array형태로 넣으면 된다. 현재 robomongo tool에 의해 작업하므로 file load는 커널에서만 가능 하다. 


다음은 paging 기법.

1
2
3
/////////////////////paging//////////////////////////////
db.users.find().limit(10);
db.users.find().skip(10).limit(10);
cs

몇개의 결과를 가져올지에 대한 함수는 limit(count) 이며, 몇개를 skip할지에 대한 함수는 skip함수를 쓰면된다. 

다음은 색인 작업. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//////////////////////index//////////////////////////////////
db.users.ensureIndex( 
  {
      "index" : 1
  }
 ); 
db.users.ensureIndex( 
  {
      "email" : 1
  }
 ); 
//compound  
db.users.ensureIndex( 
  {
      "email" : 1,
      "index" : 1
  }
 );  
cs

복합(?) 인덱스의 경우 위의 예제처럼 사용 하면 된다. 

다음은 plan 또는 explain ...
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
26
27
///////////////////plan////////////////////////  
db.users.find(
  {
      "index":{
          $lte : 50
      }
  }
).explain();  
  
  
db.users.find(
  {
      $and :[
          {
          "index" : 
              { $lte :50
            }
           },
        {
            "name""Joseph Ferguson"
        },
        {
            "email" : "josephferguson@exiand.com"
        }
      ]
  }
).explain();    
cs
위 두개의 plan을 해본 쿼리 문이다. 이것의 결과는 상당히 만족 스럽게 나온다. (plan까지 지원하다니 ....) 

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/* 1 */
{
    "queryPlanner" : {
        "plannerVersion" : 1,
        "namespace" : "test2.users"//어느 db의 어느 collection 인지. 
        "indexFilterSet" : false
        "parsedQuery" : { //실행된 쿼리
            "index" : {
                "$lte" : 50.0000000000000000
            }
        },
        "winningPlan" : {
            "stage" : "FETCH",
            "inputStage" : { //index를 탔을때 쿼리가 실행되는 단계를 나타냄. 
                "stage" : "IXSCAN"//인덱스를 통해서 검색. 
                /**
                *
                COLLSCAN for a collection scan
                                IXSCAN for scanning index keys
                                FETCH for retrieving documents
                                SHARD_MERGE for merging results from shards
                */
                "keyPattern" : { 
                    "index" : 1.0000000000000000
                },
                "indexName" : "index_1",
                "isMultiKey" : false//compound 키 사용 여부. 
                "direction" : "forward",
                "indexBounds" : {
                    "index" : [ 
                        "[-inf.0, 50.0]"
                    ]
                }
            }
        },
        "rejectedPlans" : []//인텍스가 여러개일 경우 색인하지 않을 인덱스 값의 이름이 들어있다. 
    },
    "executionStats" : {
        "executionSuccess" : true,
        "nReturned" : 51,//document 개수
        "executionTimeMillis" : 0,//실행 시간
        "totalKeysExamined" : 51//검색에 사용한 index를 통해서  개수. 
        "totalDocsExamined" : 51//collection에서 검색한 개수. 
        "executionStages" : { 
            "stage" : "FETCH",
            "nReturned" : 51// return 된 document 수. 
            "executionTimeMillisEstimate" : 0,
            "works" : 52
            "advanced" : 51
            "needTime" : 0,
            "needFetch" : 0,
            "saveState" : 0,
            "restoreState" : 0,
            "isEOF" : 1,
            "invalidates" : 0,
            "docsExamined" : 51,
            "alreadyHasObj" : 0,
            "inputStage" : {
                "stage" : "IXSCAN",
                "nReturned" : 51,
                "executionTimeMillisEstimate" : 0,
                "works" : 52,
                "advanced" : 51,
                "needTime" : 0,
                "needFetch" : 0,
                "saveState" : 0,
                "restoreState" : 0,
                "isEOF" : 1,
                "invalidates" : 0,
                "keyPattern" : {
                    "index" : 1.0000000000000000
                },
                "indexName" : "index_1",
                "isMultiKey" : false,
                "direction" : "forward",
                "indexBounds" : {
                    "index" : [ 
                        "[-inf.0, 50.0]"
                    ]
                },
                "keysExamined" : 51,
                "dupsTested" : 0,
                "dupsDropped" : 0,
                "seenInvalidated" : 0,
                "matchTested" : 0
            }
        },
        "allPlansExecution" : []
    },
    "serverInfo" : {
        "host" : "localhost",
        "port" : 35001,
        "version" : "3.0.4",
        "gitVersion" : "0481c958daeb2969800511e7475dc66986fa9ed5"
    }
}
cs


위 결과는 첫번째 예제를 실행 할때 나오는 결과 인데.. 중요한 key들이 몇개 보인다. 


state 경우 값이 COLLSCAN 인경우는 index를 타지 않았을 경우 값이 찍히고, 탔을 경우 IXSCAN 요런 값이 찍히게 된다. 


또 위 두번째 예제를 실행하면 rejectedPlans 에 key에 단일 색인 키들이 들어 갈것이다. 위 주석을 보고 참고 하면 된다. 





posted by 제스트
:
개발관련/MongoDB 2015. 11. 17. 11:12
1
2
db.crudtest.find();
 
cs

특정 collections의 데이터를 전체 가져올때 find()함수로 호출한다. 



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
db.crudtest.find(
    {
        $and: [{
            "name":"hwang"
        },{
            
             "id":"wargen"
        }]
    }
 );
 
db.crudtest.find(
    {
        $or: [{
            "id":"wargen"
        },{
            
            "idx":2
        }]
    }
 )    
cs

 

and, or 검색은 위와 같이 $and, $or 의 명령어로 array 를 선언후 object 형태로 찾고자 하는 field를 선언한다. 


특정 배열의 값을 찾고자 할때는 다음과 같이 선언한다. 


1
2
3
4
5
6
7
8
9
10
11
12
13
db.crudtest.find(
    {
        "language.0""java"
    }
);
    
db.crudtest.find(
    {
        "language" : {
            $all : ["js","java"]
            }
    }
 )     
cs


$all의 경우 array의 값이 있는 것들을 전체 다 찾아준다. 


다음은 mongodb의 꽃(?)이라 할수있는 변수 저장 이다. 

1
2
3
4
5
6
7
8
9
10
11
12
var temp = db.crudtest.find(
    {
       "type": {
           $ne : null
       }
    },
    {
        "type":1
    }
 );      
temp;
 
cs
위의 예제는 type이라는 필드에 값이 널이 아니고 type 필드에 값이 있는 document를 찾는 예제이다. 그런데 저 쿼리(?)를 temp라는 변수에 저장 후 temp;를 실행하면 결과가 화면에 나올것이다. 


이때 다시한번 temp; 를 하면 값이 나오지 않을 것이다. 이를 커서라 한다. 커서에 저장된 값 리턴될 값을 저장하는것이 아니고 실행될  쿼리를 저장한다. 그러므로 변수를 호출하면 쿼리가 호출되므로 커서의 값은 사라진다.


위의 예제의 값을 저장하고 싶다면 다음과 같이 생성해야한다. 


1
2
3
4
5
6
7
8
9
10
11
12
13
 
var returnVal = function (){
    while(temp.hasNext()){
    var currentData = temp.next();
        for(var key in currentData.type){
            print(key);
        }
    }
};
 
    
    
returnVal();    
cs

js랑 똑같다. =_=; 



mongodb도 <, >, <=, >= 이런것들을 지원을 한다. 

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
26
27
28
29
30
31
db.crudtest.find(
    {
        "idx" : {
            $lt : 2
        }
    }
);
    
db.crudtest.find(
    {
        "idx" : {
            $lte : 2
        }
    }
);    
    
db.crudtest.find(
    {
        "idx" : {
            $gte : 2
        }
    }
);        
 
db.crudtest.find(
    {
        "idx" : {
            $gt : 2
        }
    }
);        
cs


이상 find는 끝....

posted by 제스트
: