본문 바로가기
국비교육

MongoDB 수업 2일차 - 쿼리

by Diligejy 2019. 4. 16.

1. 질의 : 하나의 쿼리를 명시하는 키워드 mongoDb는 6개 정도의 질의를 구현한다.

 

    1) 키 - 값 질의 : 특정필드와 맵핑되는 값을 포함하는 문서를 말한다. 

                          주 KEY에 대한 값을 리턴하는 경우를 말한다.

    2) 범위 : 특정범위에 포함되는 값을 말한다. (비교 연산자)

    3) 공간 질의 : 선, 원, 다각형 등에 대한 공간 근삿값

    4) 문자열 탐색 질의 : 논리 연산자를 통해서 특정 문자열에 결과값.

    5) 집합 질의 : 그룹함수를 지칭하며 count, min, max, average 등을 이용한 결과값

    6) mapreduce query : javascript로 표현되는 복잡한 데이터를 데이터베이스에 실행해 반환하는 질의를 말함.

 

2. 컬렉션을 생성한 다음 키에 대한 필드 이름의 조건

    1) $로 시작할 수 없다.

    2) 255크기 내에 작성한다.

    3) 연산자를 포함할 수 없다.

    4) null(공백)이 중간에 들어갈 수 없다.

    5) 필드 이름은 하나의 컬렉션 내에서 유일한 값으로 존재한다.

    6) 전체 문서의 크기가 16M 제한적이다. (네트워크의 대역폭)

    7) 만일 문서가 대용량(16M 이상) GridFS api를 사용해서 구현한다.

 

3. 문서에 대한 정보 (외부적인 상태)

    1) mongod.lock : 서버의 프로세스 ID를 저장한다.

    2) .0 파일 (.ns) : 메타데이터를 네임스페이스 단위로 저장한다.

    3) 2번의 크기는 ns 16M를 넘을 수 없다. - 28000개의 네임스페이스 하나의 데이터베이스는 컬렉션과

       색인의 개수를 최대 28000개를 생성할 수 있다.

        --nssize arg ( = 16) 사이즈는 늘릴 수 있으나 16M 단위로 처리한다.

    4) test.0(64M), test.1(128M) 등의 파일은 순수 데이터 파일을 저장한다.

        파일의 용량은 2GB까지가 최대이다.

    5) Mongo는 데이터저장소의 크기를 정적으로 관리한다.

 

내부적인 상태를 확인 --db.stats(1024);

 

자료를 입력했을 경우 몽고 드라이버의 동작

    1) MongoDB에 삽입되는 문서의 고유 번호인 ID인 _id로 필드와 값을 생성한다.

    2) 문서를 mongodb의 bson으로 변환한다 (storage.bson) --dbpath

    3) 네트워크 소켓을 통해서 데이터베이스로 데이터를 전달한다. (node.js)

 

 

    1). Score 이름과 수학점수를 출력해보자.

    db.Score.find({}, {name:1, mat:1});

 

    2) Score의 수학점수 중, 70점 이상만 출력.

 

    3) Score의 이름과 국어점수를 출력하되 국어점수가 80점 이상만 출력해보자.

    db.Score.find({kor : {$gte : 80}}, {name:1, kor:1});

 

    4) Score의 이름과 국어점수를 출력하되 국어점수는 80점 이상을 출력하고 국어점수의 합도 구해보자.

     // sr이 레코드가 있다면 한 줄씩 읽어서 총점을 구하라.

     var sr = db.Score.find({kor: {$gte:80}}, {name:1, kor:1});

     print(sr);

     var tot = 0;

     while(sr.hasNext()){

     res = sr.next();

     print(res.name + " " + res.kor);

     tot += res.kor;

     print("tot = " + tot);

    

    }

    print("tot="+tot);

 

4. function

   var sr = db.Score.find({kor : {$gte : 80}}, {name:1, kor:1});

   sr.forEach( function(x) {

                         print(x.name);

                 });

 

    5) Score의 전체 내용을 출력하되 이름, test중 midterm만 출력해보자.

        var s = db.Score.find();

        s.forEach(function(x){

                if(x.test == "midterm"){
                print(x.name + ":" + x.test);  

             }
        });

    6) Score 이름이 a로 시작되는 레코드를 출력하자

        db.Score.find({name : /^a/})

 

    7) Score이름이 a로 시작하거나 e로 시작되는 레코드를 출력하자.

         db.Score.find({ $or: [ {name: /^a/ }, { name: /^e/ } ] } );

 

    8) Score에서 test가 m으로 시작하는 객체의 개수를 구해보자.

       db.Score.find().count(); --전체개수

     db.Score.find({test : /^m/}).count();

    

    9) Score 출력하되 중복값 없이 출력하자.

        db.Score.distinct("name");

 

    10) distinct을 이용해서 영어점수가 80점 이상의 학생의 이름을 출력하자.

        db.Score.distinct("name", {eng : {$gte:80}});

 

    11) 이름과 test를 출력하되 이름을 오름차순으로 출력해보자.

        db.Score.find({}, {"name" : 1, "test" : 1}).sort({"name" : 1});

        db.Score.find({}, {"name" :1, "test" : 1}).sort({"name" : -1});

 

     12) sort(), limit(), skip()

         sort() + limit() => 최대값, 최소값

         영어의 점수가 가장 높은 레코드를 출력하라. 

        db.Score.find().sort({eng:-1}).limit(1);

 

     13) 국어점수가 가장 낮은 레코드를 출력하라.

         db.Score.find().sort({kor:1}).limit(1);

 

     14) 전체 레코드 중 2개를 건너뛰고 3개를 출력하라. 

          db.Score.find().skip(2).limit(3);

 

     15) 전체 레코드 중 2개를 건너뛰고 3개를 출력하되 수학점수를 내림차순으로 출력하라.

         db.Score.find().skip(2).limit(3).sort({mat:1});

 

5.

    1) db.Score.group( { key : ..., initial: ..., reduce : ...[, cond: ...] } )

    - key : 필드이름

    - initial : reduce의 초기값을 지정

    - reduce : 그룹으로 집합 연산

    - cond : 조건 

    - keyf : key 필드의 조건을 지정

    - finalize : 명시적으로 initial에서 선언한 객체를 소멸

 

    2) test를 그룹별로 출력하자.

    db.Score.group({
      key : {test : true},
      initial : {},
      reduce : function(cur, result){}
      });

 

    3) test로 그룹핑 하되 국어점수가 90점 이상인 레코드만 출력하자.

        db.Score.group({

         key : {test : true},

         initial : {},

         reduce : function(cur, result){

         print(cur.name);

         },

         cond : {kor : {$gte : 90}}

        });

         cur : 현재 원시데이터

         result : 리턴 데이터

 

    4) test를 그룹화 하되 국어점수의 개수를 구하라.

        db.Score.group({ key : ..., initial : ..., reduce : ...[, cond: ...]})  

    db.Score.group(

    "key" : {"test" : true},
   "initial" : {
            "countkor" : 0
    },
   "reduce" : function(obj, prev){
          if(obj.kor != null){
               if(obj.kor instanceof Array)
                       prev.countkor += obj.kor.length;
                  else prev.countkor++;
             }
           }
     });

    5) test 그룹화를 하고 국어는 최고점수, 영어는 최저 점수를 출력해보자.

      db.Score.group({

      "key" : {"test" : true},

      "initial" : {

               

        }

      "reduce" : function(obj, prev) {

               prev.maxkor = isNaN(prev.maxkor) ? obj.kor : Math.max(prev.maxkor, obj.kor);

               prev.mineng = isNaN(prev.mineng) ? obj.eng : Math.min(prev.mineng, obj.eng);

       }

     }
      cond : 

});

     6) 국어는 90보다 크고 영어는 80보다 작은 값으로 조건문으로 주고 

         국어의 합, 영어의 최대값, 수학의 평균을 구해보자. 

  db.Score.group({
... "key" : {},
... "initial" : {"sumkor" : 0, "summat" : 0, "countmat" : 0},
... "reduce" : function(obj, prev) {
...         prev.sumkor += obj.kor;
...         prev.maxeng = isNaN(prev.maxeng) ? obj.eng : Math.max(prev.maxeng, obj.eng);
...         prev.summat += obj.mat;
...         prev.countmat++;
... },
... "finalize" : function(prev){
...       prev.averagemat = prev.summat/prev.countmat;
...       delete prev.summat;
...       delete prev.countmat;
... },
... "cond" : {kor : {$gt : 90}, eng : {$lt : 80}}
... });

 

 

6. 다음과 같이 추가한다.

    db.Product.save({Name : "notebook", Price : 200, Category : "material"});

    db.Product.save({Name : "pencil", Price : 80, Category : "material"});

    db.Product.save({Name : "salad", Price : 220, Category : "food"});

    db.Product.save({Name : "others", Price : 20, Category : "material"});

    db.Product.save({Name : "bread", Price : 100, Category : "food"});

 

    여기서 퀴즈 

    insert와 save의 차이는?
    insert : 동일한 데이터가 있을 때 추가로 삽입

    save : 동일한 데이터가 있을 때 덮어쓰기 

   

    1) MongoDB에서 집계처리하는 방법 3가지

        ⓐ MongoDB / db.aggregate([pipeline], {options}) - performs a collectionless aggregation on this database; returns a cursor

 

       SQL에서 사용하는 GROUP BY 절에 맵핑되는 구문과 내장함수를 제공한다.

       Shell에서 쿼리와 동일하게 사용한다.

       일부 처리 ($group, $sort)는 샤딩할 때 사용 

       

       ⓑ Mongo Map / Reduce 기능을 가진 내장 함수를 사용한다.

       (db.Score.mapreduce(mapFunction , reduceFunction ,  )

        db.Score.aggregate( [pipeline],  <optional params>)

        장점 : 샤드에 강함, 분산에 사용된다. ⓐ번에서 사용할 수 없는 기능을 처리한다.

        단점 : 복잡하다. JS 숙련을 요구.

        

        ⓒ 데이터 처리 집계를 미들웨어로 연계하여 처리

            

 

     2) 

           ⓐ 수집 -> 전처리 -> 적재 (하둡)

                  

           ⓑ MongoDB / Aggregate 컬렉션 (Aggregate Framework) $ 제공한다.

               SQL                        Aggregate

               where                        $match

               group by                    $group 

               having                        $match

               select                         $project

               order by                     $sort

               limit                           $limit

               sum()                          $sum

               count()                        $sum

               average()                     $avg

 

           ⓒ id와 가격만 출력

              db.Product.aggregate([{$project : {_id : 0, Price : 1}}]);

 

            ⓓ 이름과 가격 출력

              db.Product.aggregate([{$project :{_id:0, Name:1, Price:1}}]);

        

            ⓔ 가격과 Category를 출력하되 오름차순으로 정렬한다.

               db.Product.aggregate([{$project : {_id:0, Price:1, Category :1}},

                   {$sort : {Price : 1}}

                ]);

 

            ⓕ 이름과 가격을 출력하되 이름을 내림차순으로 정렬해보자. 

                > db.Product.aggregate([{$project : {_id:0, Name : 1, Category : 1}},
                ... {$sort : {Name : -1}}
                 ... ]);

 

 

 

'국비교육' 카테고리의 다른 글

MongoDB 수업 4일차  (0) 2019.04.18
MongoDB 수업 3일차  (0) 2019.04.17
MongoDB 수업 1일차 - 개론  (0) 2019.04.15
국비교육 76일차  (0) 2019.03.26
국비교육 75일차  (0) 2019.03.25

댓글