Replication, Sharding 이란?
  - 데이터를 여러 서버에 분할하는 것을 말한다. MongoDB의 데이터 분할은 상황에 따라 
    각 Shard로 이동되어 MongoDB 이용자(앱, 웹)는 여러 서버를 인식하지 않고
    데이터를 적재시킨다.

  - 복제는 동일한 데이터의 사본을 여러 DB에 가지고 있는 반면, 
    Sharding은 다른 데이터를 여러 서버(DB)에 가진다.

  - 보통의 MongoDB 운영은 Sharding + ReplicaSet 구성

1. 샤드 : 실제로 데이터가 저장되어 있는 mongod 프로세스이며, 하나의 문서는 하나의 샤드에
            저장되어 샤드간의 데이터 복제는 하지 않는다. ReplicaSet(복제)를 구성하는 것을 권장

2. config server : 샤드 메타 데이터를 관리하는 mongod 프로세스로 단일 장애 지점이 된다.

3. mongos server : 샤드의 라우팅 프로세스이다. 샤드와 클라이언트를 연계시킨다.
                          필요하다면 여러 개의 mongos 서버를 가질 수 있다.
                          상태 값이나 데이터는 전혀 갖고 있지 않다. 연계, 실행만 시켜주는 역할

4. 샤드 키 : 데이터를 분산하는 범위의 키로 복수 지정할 수 있다.
                키에 어떤 범위의 데이터가 어떤 샤드에 저장되는지를 MongoDB가 관리하고
                데이터의 편차에 따라 자동으로 조정된다.

5. 청크 : 샤드의 덩어리를 말하며 분산 데이터의 단위
            구체적으로는 컬렉션의 연속된 범위의 데이터의 문서를 말한다.
            청크의 최대 크기에 도달하면 분할된 샤드가 가지고 있는 청크 수에 따라 
            필요한 경우 다른 샤드로 이동된다. 청크의 최대 크기는 변경할 수 있다.

 

============================================================================

1. mongod 3개를 실행하여 shard를 구성 - 각각의 dbpath, logpath, port를 다르게 해주고 replSet의 별칭을 지정

mongod --shardsvr --dbpath C:\data\mydata02 --logpath C:\data\mydata02\log\monod1.log --port 27030 --replSet RS 
mongod --shardsvr --dbpath C:\data\mydata03 --logpath C:\data\mydata03\log\monod2.log --port 27031 --replSet RS 
mongod --shardsvr --dbpath C:\data\mydata04 --logpath C:\data\mydata04\log\monod3.log --port 27032 --replSet RS

 

 

2. Shard와 Replica Set을 구성

mongo localhost:27030
use admin

var config = {
    _id: 'RS', 
    members: [
        {_id:0, host: 'localhost:27030'},
        {_id:1, host: 'localhost:27031'},
        {_id:2, host: 'localhost:27032'}
    ]
}

rs.initiate(config)

이후 각각의 mongo로 접속해 확인

 

3. mongod의 config server를 설정해 라우팅 기능을 부여

start mongod --configsvr --dbpath C:\data\mongoc1 --logpath C:\data\mongoc1\log\mongoc.log --port 27011 --replSet CRS 
start mongod --configsvr --dbpath C:\data\mongoc2 --logpath C:\data\mongoc2\log\mongoc.log --port 27012 --replSet CRS 
start mongod --configsvr --dbpath C:\data\mongoc3 --logpath C:\data\mongoc3\log\mongoc.log --port 27013 --replSet CRS

 

4. config server의 Replica Set을 구성

mongo localhost:27011
use admin

var conf = {
    _id : 'CRS',
    version : 1,
    members: [
        {_id : 0, host:'localhost:27011'},
        {_id : 1, host:'localhost:27012'},
        {_id : 2, host:'localhost:27013'}
    ]
};

rs.initiate(conf)

 

5. mongos를 통해 라우팅을 지정

mongos --configdb CRS/localhost:27011,localhost:27012,localhost:27013 --port 1000
mongo localhost:1000

sh.addShard('RS/localhost:27030,localhost:27031,localhost:27032');

sh.status로 addShard 전과 후 비교

 

addShard하기 전의 sh.status()
addShard 후의 sh.status(). shards: 에 추가된 내용 확인

 

'데이터과학자 - 강의 > javascript & mongoDB' 카테고리의 다른 글

210615 MongoDB - mongoimport, mongoexport  (0) 2021.06.16
210615 MongoDB - aggregate, mongofiles  (0) 2021.06.15
210614 MongoDB - aggregate  (0) 2021.06.14
210611 MongoDB  (0) 2021.06.12
210610 MongoDB  (0) 2021.06.10

mongoimport, mongoexport
option
  -h[--host], -u[--username], -p[--password], -d[--db], -c[--collection], -f[--fields], --file, --drop, --out 등등

c:test에 myaddr.json 생성
{ "address : [ { name : "홍길동", addr : "서울시 서초동" }, 
                  { name : "정길동", addr : "제주시 제주동" } ] }


ex)

mongoimport --db newdb --collection addrtest --file myaddr.json

mongoexport --db my_score -c score --out myScore.json

mongoexport -d geotest -c places --out myplaces.json

mongoexport -d newdb -c addrtest --out myexport.json


============================================================================

Q1) myaddr.json을 newdb의 test_addr이라는 컬렉션으로 import
mongoimport --db newdb --collection test_addr --file myaddr.json

Q2) addrtest라는 컬렉션을 myexport.json으로 export한다.
mongoexport -d newdb -c addrtest -o myexport.json

Q3) addrtest라는 컬렉션을 mycsv.csv로 export한다.
mongoexport -d newdb -c addrtest -o mycsv.csv

Q4) Score라는 컬렉션을 myScore.csv로 export
mongoexport -d my_score -c score -o myScore.csv

Q5) Score라는 컬렉션을 myScore.tsv로 export
mongoexport --db my_score --collection score --out myScore.tsv

Q6) myScore.csv를 newdb의 test_myScore라는 컬렉션으로 import
mongoimport --db newdb -c test_myScore --file myScore.csv

Q7) Score라는 컬렉션을 이름, 국어 점수만 a.txt로 export 해보자.
mongoexport -d my_score -c score --fields name,kor -o a.txt

Q8) score 컬렉션에서 국어점수가 60이상인 문서만 b.txt로 export해보자.
mongoexport -d my_score -c score -q "{\"kor\":{\"$gte\":65}}" -o b.txt

'데이터과학자 - 강의 > javascript & mongoDB' 카테고리의 다른 글

210615 MongoDB - Replication, Sharding  (0) 2021.06.17
210615 MongoDB - aggregate, mongofiles  (0) 2021.06.15
210614 MongoDB - aggregate  (0) 2021.06.14
210611 MongoDB  (0) 2021.06.12
210610 MongoDB  (0) 2021.06.10

1. mongofiles 설치 및 운용

2. aggregate 약간의 복습

 

============================================================================

mongofiles는 4.2까지는 server를 설치할 때 같이 설치되어 있었으나 4.4부터는 빠지게 되었다.

그래서 직접 설치해줘야 함.

https://www.mongodb.com/try/download/database-tools?tck=docs_databasetools 

위의 주소에서 다운받아 설치한다.

 

설치가 잘 되었는지 확인하고 설치된 경로를 복사한다.

 

복사한 경로를 환경변수의 시스템 path에 등록한다.(많이 했으니 접속 방법은 생략)

 

윈도우 커맨드 창에서 mongofiles가 실행되는지 확인 후 실행이 되면 설치 완료

 

mongofiles

[형식]

mongofiles <options> <connection-string> <command> <filename or _id>
  - 일반적으로 mongoDB 저장할 수 있는 문서의 크기 16MB 상한
  - GridFS MongoDB를 16MB 단위로 분할해서 (입출력) 하기위한 인터페이스

 

mongofiles를 통해 db에 파일을 저장하고 해당 db에 접속하면 

fs.chunks와 fs.files collection이 생성된 것을 확인할 수 있다.

chunks collection의 각 document는 GridFS를 통해 분할된 각각의 청크들이 BSON 형식으로 저장되어있다.

files collection의 각 document는 GridFS의 파일들이다.

 

============================================================================

Q1) images 데이터베이스에 1.jpg를 올리고 싶다.
mongofiles -v -d images put 1.jpg

결과  ==> 위에서 좌->우 순서대로 명령을 실행
2021-06-15T14:48:16.465+0900    using write concern: &{majority false 0}
2021-06-15T14:48:16.486+0900    will listen for SIGTERM, SIGINT, and SIGKILL
2021-06-15T14:48:17.113+0900    connected to node type: standalone
2021-06-15T14:48:17.115+0900    connected to: mongodb://localhost/
2021-06-15T14:48:17.115+0900    handling mongofiles 'put' command...
2021-06-15T14:48:17.115+0900    adding gridFile: 1.jpg

2021-06-15T14:48:17.145+0900    creating GridFS gridFile '' from local gridFile '1.jpg'
2021-06-15T14:48:17.188+0900    copied 55476 bytes to server
2021-06-15T14:48:17.188+0900    added gridFile: 1.jpg


Q2)fs.files에 있는 파일의 목록을 확인하고 id를 찾아서 fs.chunks에서 데이터를 확인하자
ObjectId("60c83f21c779a271cff19592")
db.fs.chunks.find( {files_id : ObjectId("60c83f21c779a271cff19592") } )

show collections 하면 
fs.chunks
fs.files가 있는데 chunks에는 복사된 원본파일이 bson 타입으로 저장되어있고
files는 파일명이나 이런게 관리되고 있다

a.txt
ObjectId("60c840caca9b3786a53d8374")
db.fs.chunks.find( {files_id : ObjectId("60c840caca9b3786a53d8374") } )

c.json
ObjectId("60c8415b6e4521e1e3e9f9f2")
db.fs.chunks.find( {files_id : ObjectId("60c8415b6e4521e1e3e9f9f2") } )


Q3) 목록확인
mongofiles -v -d images list
test 폴더의 원본 지우기


Q4) d.mp4로 영상을 images db에 put한 다음 몽고 접속 후
use images로 이동해서 내용을 확인 (data는 출력x)
ObjectId("60c84e282c9e6a6a2fc00f10")
db.fs.chunks.find( { files_id : ObjectId("60c84e282c9e6a6a2fc00f10") }, { data : 0 } )

 

============================================================================

2d : 좌표 평면 계산 - 하나의 인덱스
2dsphere : 좌표, GeoJson - 위치 상관 없이 인덱스, 복합 인덱스

플레이데이터 좌표
37.486429304535626, 127.02068640002402

use geotest

var baseLng = 127.02068;
var baseLat = 37.48642;

var diffLng = 127;
var diffLat = 37;

var categories = [ '커피', '은행', '편의점' ];

for ( var i = 1; i <= 100; i++ ){
    var myLng = baseLng + ( Math.random() * diffLng );
    var myLat = baseLat + ( Math.random() * diffLat );

    var myCategories = categories[ Math.floor(Math.random() * categories.length) ];

    db.places.save( { location : [ myLng, myLat ], 
                          category : myCategories } );
};

 

============================================================================

Q1) 인덱스를 작성한다
db.places.getIndexes();
db.places.ensureIndex( { location : "2d", category : 1 } );


Q2) -180~180 범위를 벗어나는 문서를 삭제하세요
db.places.find({ location : { $gt : [180, 180] } }, {  }).count();
db.places.deleteMany( { location : { $gt : [180, 180] } } );

db.places.aggregate([
    { $match : { location : { $lte : 180 } } },
    { $count : "location" }
]);


Q3) 편의점을 찾아보자
db.places.find( { category : "편의점" } );

Q4) 은행을 찾아보자
db.places.aggregate([
    { $match : { category : "은행" } }
]);

Q5) 커피를 찾아보자
db.places.find( { category : "커피" } );


Q6) [  ] 근처에 편의점, 은행, 커피 중 가장 가까운 10개를 찾아보자
db.places.find( { location : { $near : [ 150, 50 ] } } ).limit(10);

db.places.aggregate([
    { $match : { location : { $near : [ 150, 50 ] } } },
    { $limit : 10 }
]);


Q7) 위 결과 중 가장 가까운 결과인 { "_id" : ObjectId("60c80bda3794062106b465d1"), 
     "location" : [ 147.91607640820177, 53.23275855594654 ], "category" : "은행" }에서 
     가장 가까운 5개의 편의점, 은행, 커피를 찾아보자
db.places.find( { location : { $near : [ 147.91607640820177, 53.23275855594654 ] } } ).limit(5);


Q8) 00근처에서 근방 10 거리에 있는 은행을 찾아보자.
db.places.find( { location : { $near : [ 150, 50 ], $maxDistance : 10 }, category : "은행" } );


Q9) 00근처에서 가장 멀리있는 편의점을 3개 찾아보자
db.places.find( { location : { $near : [ 150, 50 ] }, category : "편의점" } ).sort( { location : -1 } ); -- X

 

$near의 결과물은 가까운 순으로 정렬된다. sort는 가까운 순으로 정렬하지는 않는다. 즉,

db.places.find( { location : { $near : [ 150, 50 ] }, category : "편의점" } )의 결과와

db.places.find( { location : { $near : [ 150, 50 ] }, category : "편의점" } ).sort( { location : 1 } )의 결과는 같지 않다.

 

그래서

db.places.find( { location : { $near : [ 150, 50 ] }, category : "편의점" } ).sort( { location : -1 } )는 

해당 문제의 답이 아니다.

 

이 문제의 답은 고민해봐야 할 듯

 

'데이터과학자 - 강의 > javascript & mongoDB' 카테고리의 다른 글

210615 MongoDB - Replication, Sharding  (0) 2021.06.17
210615 MongoDB - mongoimport, mongoexport  (0) 2021.06.16
210614 MongoDB - aggregate  (0) 2021.06.14
210611 MongoDB  (0) 2021.06.12
210610 MongoDB  (0) 2021.06.10

다양한 패턴의 데이터가 있다.
txt, csv(txv), json, xml, sql(pandas, hive, spark)

=================================================================
db.product.getIndexes();
db.product.aggregate([
    { $project : { _id : 0, name : 1, price : 1, category : 1 } },
    { $match : { name : "bread" } }
]);

--> 기본 컬렉션의 인덱스를 확인
db.product.getIndexes();

--> 인덱스를 추가 설정
db.product.ensureIndex( { name : 1 } );

--> 추가된 인덱스 필드의 값을 찾아서 실행 결과를 확인
db.product.find({name:"bread"}).explain();

--> 인덱스 삭제
db.product.dropIndex( { name : 1 } );

--> 이름순으로 정렬
db.product.find().sort( {name : 1} );

--> bread찾아서 실행결과를 확인
db.product.find( { name:"bread" } ).explain();

=================================================================
https://docs.mongodb.com/manual/geospatial-queries/
https://docs.mongodb.com/manual/core/2dsphere/
https://docs.mongodb.com/manual/core/2d/
MongoDB 지리 인덱스 쿼리 구성
1. 지리공간 데이터를 저장하는 방법
  1-1. 좌표 : 종래의 좌표를 나타내는 데이터, 주로 평면상의 점을 사용하고 표현할 수 있는 도형의 점
        { loc : [ 10, 20 ] } - 점만 사용
  1-2. GeoJSON : 새로운 다양한 형태를 표현할 수 있는 데이터, 주로 지구 표면의 위도, 경도를
                       다루는데 사용된다.
        { loc : { type : "Point" , coordinates : [ 10, 20 ] } }

2. 쿼리 유형 세가지
  2-1. 내포된 쿼리 - $geoWithin : 다각형 좌표, 사각 좌표, 원형 좌표
        지구 표면에 원형으로 검색된 쿼리 (2d / 2dsphere) 모두 사용

  2-2. 겹침 - $geoIntersects : 2dsphere 사용. 점, 선, 다각형

  2-3. 근거리 - $near : 2d / 2dsphere - 점과의 거리, 좌표와 점과의 거리


3. 검색조건
https://docs.mongodb.com/manual/reference/geojson/
  - GeoJSON : 점, $geometry : { type : "Point", coordinates : [x, y] }
  - GeoJSON : 직선, $geometry : { type : "LineString", coordinates : [ [x, y], [x2, y2] ] }
  - GeoJSON : 다각형, $geometry : { type : "Polygon", coordinates : [ [x, y], [x2, y2], ... ] }
  - GeoJSON : GeoJSON 집합, $geometry : { type : "GeometryCollection", geometries: [ {  }, {  } ] }

https://docs.mongodb.com/manual/reference/operator/query-geospatial/
  - 좌표 : 점 [x1, y1]
  - 좌표 : 사각형 $box : [ [ <bottom left coordinates> ], [ <upper right coordinates> ] ]
  - 좌표 : 다각형 $polygon : [ [ <x1> , <y1> ], [ <x2> , <y2> ], [ <x3> , <y3> ], ... ]
  - 좌표 : 원형 $center : [ [ <x>, <y> ] , <radius> ]
  - 좌표 : 지구 표면의 원형 $centerSphere : [ [ <x>, <y> ], <radius> ]

db.createCollection("location")
db.location.save( { _id : "A", position : [0.001, -0.002] } );
db.location.save( { _id : "B", position : [1.0, 1.0] } );
db.location.save( { _id : "C", position : [0.5, 0.5] } );
db.location.save( { _id : "D", position : [-0.5, -0.5] } );

db.location.ensureIndex( { position : "2d" } );  -- 여기서 인덱싱은 필수다. 이걸 해줘야 좌표로 인식함

db.location.find( { position : { $within : { $box : [ [0.25, 0.25 ], [1.0, 1.0] ] } } } );

현재 나의 위치가 0,0 주변의 약국을 동그라미로 찾았더니 ABCD의 위치가 리턴되더라
db.location.find( { position : { $within : { $center : [ [0, 0], 1.42 ] } } } );

0,0 에서 ~ 0.75 사이 거리의 약국을 찾고 싶다.
db.location.find( { position : { $near : [0,0], $maxDistance : 0.75 } } );

=================================================================
Q1) product 전체 내용을 출력해보자. _id는 빼고 출력하자
db.product.find({}, {_id : 0});


Q2) id와 가격을 출력해보자
db.product.aggregate( [ 
                                    { $project : {_id : 1, price : 1} }
                            ] );

db.product.aggregate( [ 
                                    { $project : {price : 1} }
                            ] );

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


Q3) 이름과 가격만 출력해보자
db.product.aggregate([
    {
        $project : { _id : 0, price : 1, name : 1 }
    }
]);


Q4) 가격과 카테고리만 출력하는데 가격 오름차순으로 정렬해서 출력해보자
db.product.aggregate([
    {
        $project : { _id : 0, price : 1, category : 1 }
    },
    {
        $sort : { price: 1 }
    }
]);


Q5) 이름(목록)과 가격만 출력하는데 이름을 내림차순으로 정렬해보자
db.product.aggregate([
    { $project : { name : 1, price : 1, _id : 0 } },
    { $sort : { name : -1 } }
]);


Q6) $project 도움말로 가서 별칭을 주는 것을 확인한 후 아래와 같이
     이름(목록만) 출력해보자
db.product.aggregate([
    { $project : { _id : 0, alias_name : "$name" } }
]);


Q7) name을 목록, price를 가격, category를 타입으로 별칭을 줘서 출력해보자
db.product.aggregate([
    { $project : { _id : 0, 목록 : "$name", 가격 : "$price", 타입 : "$category" } }
]);


Q8) 상품의 목록을 출력하고 inc_price라는 별칭을 주고 가격에 100을 더한 값을 출력해보자
      도움말 $add
db.product.aggregate([
    { $project : { _id : 0, name : 1, inc_price : { $add : [ "$price", 100 ] } } }
]);


Q9) 카테고리로 그룹화를 한 다음 최대 가격을 출력해보자
      도움말 $max, $group
db.product.aggregate([
    { $group : { _id : "$category", max_price : { $max : "$price" } } }
]);


Q10) 카테고리로 그룹화를 한 다음 최대 가격을 출력해보자
      도움말 $min, $group
db.product.aggregate([
    { $group : { _id : "$category", min_price : { $min : "$price" } } }
]);


Q11) 상품목록을 출력하고 가격의 합과 가격이 평균 및 목록의 개수를 구하자
db.product.aggregate([
    { $group : { _id : "$category", total : { $sum : "$price" }, 평균 : { $avg : "$price" }, count : { $sum : 1 } } }
]);


Q12) 상품목록을 출력하고 그룹화 한 다음 개수를 구해보자. 단, 위에 $sum : 1과 다르게
db.product.aggregate([
    { $project : { category : 1, count : { $literal : 1 } } },
    { $group : { _id : "$category", count : { $sum : "$count" } } }
]);

db.product.aggregate([
    { $project : { category : 1, count : { $literal : 1 } } },
    { $group : { _id : "$category", count : { $sum : "$count" }, total : { $sum : "$price" } } }
]);


Q13) name에서 bread를 찾아서 출력하자
db.product.aggregate([
    { $project : { _id : 0, name : 1, price : 1, category : 1 } },
    { $match : { name : "bread" } }
]);


Q14) category에서 food만 출력
db.product.aggregate([
    { $project : { _id : 0, name : 1, price : 1, category : 1 } },
    { $match : { category : "food" } }
]);

db.product.aggregate([
    { $match : { category : "food" } }
]);


Q15) category에서 food 가격의 최대, 최소, 총합, 평균, 개수를 출력해보자
db.product.aggregate([
    { $group : { _id : "$category", max : { $max : "$price" }, min : { $min : "$price" },
                   sum : { $sum : "$price" }, avg : { $avg : "$price" }, cnt : { $sum : 1 } } },
    { $match : { _id : "food" } }
]);


Q16) 15번을 코드로 작성해보자
function map(){
    emit(this.category, { sum : this.price, min : this.price, max : this.price, cnt : 1 } );
};

function reduce(k, v){
    var r = { category : k, sum : 0, min : 10000, max : 0, cnt : 0 }
    
    v.forEach(function(vv){
        r.cnt += vv.cnt;
        r.sum += vv.sum;
        r.min = Math.min(vv.min, r.min);
        r.max = Math.max(vv.max, r.max);
    });
    return r;
};

db.product.mapReduce(map, reduce, { out : { replace : "myResult04" } } );
db.myResult04.find();

'데이터과학자 - 강의 > javascript & mongoDB' 카테고리의 다른 글

210615 MongoDB - mongoimport, mongoexport  (0) 2021.06.16
210615 MongoDB - aggregate, mongofiles  (0) 2021.06.15
210611 MongoDB  (0) 2021.06.12
210610 MongoDB  (0) 2021.06.10
210609 javascript, MongoDB  (0) 2021.06.09

저널링은?
복제시스템을 가지고 있는 샤딩분산작업을 했을 때
파일시스템이 변경됐을 때(데이터를 수정했을 때)
저널링 파일시스템이란게 발생을 해서 
커밋단계를 만들어준다.

몽고디비는 
1. 기본이 네트워크 통신이다
2. 스트림단위가 필요없다 기본이 바이너리타입이라 그래서 통신이 원활하다
   어떤 머신에 붙일 때 or 장거리로 보낼 때 유리
   비정형, 대용량 데이터 통신에 너무 원활

어제 수업
1. 프로그램 설치
2. 특징확인
3. 상태확인

MR은 기본적으로 그룹핑하고 집계한 결과

================================================================
컬렉션 생성, 연산자 활용, 집계

//score 컬렉션 생성

db.score.insert( { name : "aaa", kor : 90, eng : 80, mat : 98, test : "midterm" } )
db.score.insert( { name : "bbb", kor : 100, eng : 100, mat : 76, test : "final" } )
db.score.insert( { name : "ccc", kor : 80, eng : 55, mat : 67, test : "midterm" } )
db.score.insert( { name : "ddd", kor : 70, eng : 69, mat : 67, test : "midterm" } )
db.score.insert( { name : "eee", kor : 60, eng : 80, mat : 78, test : "final" } )
db.score.insert( { name : "fff", kor : 100, eng : 69, mat : 89, test : "midterm" } )
db.score.insert( { name : "ggg", kor : 75, eng : 100, mat : 100, test : "final" } )

=================================================================
  - count(), distinct(), sort() : -1 내림차순, limit()
        db.score.find(...).count()
        db.score.find(...).limit(n)
        db.score.find(...).skip(n)
        db.score.find(...).sort(...)

SQL Terms, Functions, and Concepts     MongoDB Aggregation Operators
WHERE                                           $match
GROUP BY                                       $group
HAVING                                          $match
SELECT                                           $project
ORDER BY                                       $sort
LIMIT                                              $limit
SUM()                                             $sum
COUNT()                                         $sum, $sortByCount
join                                                $lookup
SELECT INTO NEW_TABLE                   $out
MERGE INTO TABLE                           $merge (Available starting in MongoDB 4.2)
UNION ALL                                      $unionWith (Available starting in MongoDB 4.4)

MongoDB에서 집계처리하는 방법
  1. Aggregation 프레임워크
        SQL에서 사용하는 GROUP BY절과 SUM 등으로 이루어진다
        MongoShell에서 쿼리와 같은 방법으로 사용된다.
        일부 처리($group과 $sort)는 샤드에 대응하고, 각 샤드에서 처리한다.

  2. Map / Reduce 기능
        Map 함수, Reduce 함수를 정의해서 집계 처리한다.
        Aggregation 프레임워크에서 할 수 없는 복잡한 집계 작업을 수행하는데 사용한다.
        샤드에 대응하고 있기 때문에 분산 처리를 실시하는 것이 가능하다.

  3. 기타 집계 처리, 미들과의 연계(하둡)
        더 큰 규모로 집계 처리를 하기 때문에 다른 집계처리 미들웨어 시스템과의 연계를 한다.
        미들웨어(middleware) = 분산환경 + 네트워크 통신 + 응용프로그램과의 연계

================================================================
Q1) score의 전체 출력을 해보고 문서의 개수를 구하자
db.score.find()
db.score.find().count()


Q2) score의 이름과 수학점수만 출력해보자
db.score.find({}, {name:1 , mat:1, _id:0})


Q3) score 수학점수 중 70점 이상만 출력해보자
db.score.find({ mat : { $gte : 70 } }, { _id : 0 })
db.score.find({ mat : { $gte : 70 } }, { _id : 0 }).count()


Q4) score 이름과 국어점수를 출력하되 국어점수가 80점 이상만 출력
db.score.find({kor : {$gte : 80}}, {name : 1, kor : 1, _id : 0})


Q5) score 이름과 국어점수를 출력하되 국어점수가 80점 이상 추출해서 합을 구하자
var sr = db.score.find({kor : {$gte : 80}}, {name : 1, kor : 1, _id : 0})
sr    ==>    하면 1번은 나오는데 2번부턴 안나온다. print(sr)은 계속 나온다.

var sr = db.score.find({kor : {$gte : 80}}, {name : 1, kor : 1, _id : 0});
var tot = 0;
while (sr.hasNext()){
res = sr.next();
print(res.name + " : " + res.kor);
tot += res.kor;
print("tot = " + tot);
}
print("tot = " + tot);

ex) forEach
db.users.find().forEach( function(myDoc) { print( "user: " + myDoc.name ); } );

var sr02 = db.score.find({kor : {$gte : 80}}, {name : 1, kor : 1, _id : 0});
sr02.forEach(
function(x){
               print(x.name + " : " + x.kor);
              }
)


Q6) test가 midterm만 이름, test를 출력해보자
db.score.find({test:"midterm"},{name: 1, test:1, _id:0})
db.score.find({test:{$eq : "midterm"}},{name: 1, test:1, _id:0})

ex) forEach
var sm = db.score.find({test:"midterm"},{name: 1, test:1, _id:0})
sm.forEach(function(x){
if(x.test == "midterm"){
print(x.name + " : " + x.test);
}
})


Q7) 이름이 a로 시작하는 문서를 찾아보자 ( oracle like 'A%')
db.score.find({name : /^a/}, {_id : 0})


Q8) 이름이 a로 시작하거나 e로 시작하는 문서를 찾아보자
db.score.find( { $or : [{name : /^a/}, {name : /^e/}] }, { _id : 0 } )


Q9) score에서 test가 m으로 시작하는 문서의 개수를 구하자
db.score.find( { test : /^m/ }, { _id : 0 } ).count()


Q10) 이름을 출력하되 중복되지 않게 출력
distinct( 필드, 쿼리 )
db.score.distinct("name");
db.score.distinct("test");


Q11) 영어점수가 80점 이상인 학생의 이름을 중복되지 않게 출력해보자
db.score.distinct("name", {eng : {$gte : 80}});


Q12) next() 메소드를 사용하자 docs
https://docs.mongodb.com/manual/reference/method/db.collection.find/#mongodb-method-db.collection.find
case1)
var myCursor = db.score.find( );

var myDocument = myCursor.hasNext() ? myCursor.next() : null;

if (myDocument) {
    var myName = myDocument.name;
    print (tojson(myName));
}

case2)
var myCursor = db.score.find( );

var myDocument = myCursor.hasNext() ? myCursor.next() : null;

if (myDocument) {
   var myName = myDocument.name;
   printjson(myName);
}

case3)
var myCursor = db.score.find( );

myCursor.forEach(printjson);


Q13) test를 출력하되 이름을 오름차순으로 정렬해보자.
db.score.find({}, {name : 1, test : 1}).sort({name : 1});


Q14) 최대값, 최소값을 sort() + limit()
영어점수가 가장 높은 문서를 출력
db.score.find({}, {_id : 0}).sort({eng : -1}).limit(1);

Q15) 국어 점수가 가장 낮은 문서를 출력하자
db.score.find({}, {_id : 0}).sort({kor : 1}).limit(1);

Q16) 5개의 문서중에서 2개를 건너띄고 3줄만 출력
db.score.find({}, {_id : 0}).limit(5).skip(2).limit(3);

Q17) 5개의 문서중에서 2개를 건너띄고 3줄을 수학점수 내림차순으로 출력
db.score.find({}, {_id : 0}).sort({mat : -1}).limit(5).skip(2).limit(3);


Q18) 아래 데이터 입력 후 확인하세요 find()
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"});


Q19) 맵리듀스를 활용해서 집계를 구현해보자
        collection의 category별로 목록의 개수와 가격의 합을 구해보자
결과 : 
{ "_id" : "material", "value" : { "category" : "material", "count" : 3, "amount" : 300 } }
{ "_id" : "food", "value" : { "category" : "food", "count" : 2, "amount" : 320 } }

db.product.help()로 가서 아래를 복사해오기
db.product.mapReduce( mapFunction , reduceFunction , <optional params> )

1. mapFunction : emit을 매개인자로 집계할 key, value 값을 지정한다. 틀을 만들어 주는듯?
function mymap(){
    emit( this.category, {category : this.category, count : 1, amount : this.price} );
};
emit() : 특정 키 값별로 값을 그룹핑하는 함수

2. reduceFunction
function myreduce(key, values){
    var result = { category : key, count : 0, amount : 0 };
    values.forEach( function (v) {
        result.count += v.count;
        result.amount += v.amount;
    });
    return result;
};

3. <optional params>
db.product.mapReduce( mymap, myreduce, { out: { replace : "myResult" } } );
db.myResult.find();


Q20) score 컬렉션에서 test를 그룹화해서 개수를 구하자. (MR)myresult02
function mymap(){
    emit( this.test, { test : this.test, count : 1 } );
};

function myred(key, values){
    var result = { test : key, count : 0 }
    values.forEach( function (v) {
        result.count += v.count;
    });
    return result;
};

db.score.mapReduce(mymap, myred, { out : { replace : "myresult02" } } );
db.myresult02.find();

Q21) test 그룹화해서 국어점수 합계, 수학은 평균을 구하자 (MR)myresult03
function myMap(){
    emit(this.test, {test : this.test, kor : this.kor, mat : this.mat, count : 1});
};

function myReduce(k, v){
    var result = {test : k, sumKor : 0, avgMat : 0, count :0};
    v.forEach(function(vv){
        result.sumKor += vv.kor;
        result.count += vv.count;
        result.avgMat += vv.mat;  
    });
    result.avgMat = result.avgMat / result.count;
    return result;
};

db.score.mapReduce(myMap, myReduce, {out : {replace : "myResult03"}});
db.myResult03.find();

================================================================
번외) 빅데이터 처리 (비정형 원칙)
수집 : 척화
처리(집계) : MongnDB(js), Nosql(c, c++), 하둡(java 집계), Spark
저장 : 비정형 <-> 정형, 하둡(비정형 미들웨어), 데이터 웨어하우스(정형 미들웨어)
기본 3단계

'데이터과학자 - 강의 > javascript & mongoDB' 카테고리의 다른 글

210615 MongoDB - aggregate, mongofiles  (0) 2021.06.15
210614 MongoDB - aggregate  (0) 2021.06.14
210610 MongoDB  (0) 2021.06.10
210609 javascript, MongoDB  (0) 2021.06.09
210608 javascript  (0) 2021.06.08

몽고DB
1. 질의 : 하나의 쿼리를 명시하는 키워드, mongoDB는 6개 정도의 질의를 가진다.
    1-1. 키-값 질의 : 특정 필드(키)와 맵핑되는 값을 포함하는 문서(row, {})를 말한다.
                          주 key에 대한 값을 리턴하는 경우

    1-2. 범위 질의 : 특정 범위에 포함되는 값을 말한다. (비교연산자) 파이프라인

    1-3. 공간 질의 : 선, 원, 다각형 등에 대한 공간 근사값

    1-4. 문자열 탐색질의 : 논리연산자를 통해서 특정 문자열을 탐색

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

    1-6. MR(Map Reduce Query : 파일, db -> 데이터 -> 분철1 -> 정렬 -> 집계 ) :
        javascript로 표현되는 복잡한 데이터를 데이터베이스로 실행해 반환하는 질의


2. collection ( = table) 규칙 및 필드명 생성조건
    2-1. $로 시작할 수 없다. 대소문자 구분한다.
    2-2. 255이내로 작성한다.
    2-3. (.)연산자를 포함할 수 없다.
    2-4. 공백이 중간에 들어갈 수 없다.
    2-5. 필드 이름은 하나의 컬렉션 내에서 유일한 값으로 존재한다.
    2-6. 전체 문서의 크기가 16M로 제한적이다. (네트워크의 대역폭 때문)
    2-7. 만일 문서가 대용량(16M 이상)이라면 GridFS api(대용량 데이터 처리)를 사용해서 구현한다.

    ※ txt sql csv tsv xml json은 완전히 호환 가능 해야함


3. 문서(Document = row)에 대한 정보 (외부적인 상태)
    3-1. mongod.lock : 서버의 프로세스 ID 저장한다
    3-2. .0 파일, .ns 등의 파일 생성 : 메타 데이터를 네임스페이스 단위로 저장한다
    3-3. 2번의 크기는 ns 16M를 넘을 수 없다. - 28000개 정도의 네임스페이스 
                                                             (하나의 DB는 컬렉션과 색인수를 28000개 가진다.)
          --nssize arg(=16)
    3-4. test.0(64M), test.1(128M) 이런식으로 데이터 저장소를 확보해서 데이터를 저장한다고 하면
          파일의 용량은 2G까지가 최대이다.
    3-5. mongo는 데이터저장소의 크기를 정적으로 관리한다.

ex) 서비스에서 몽고디비 속성확인 주소복사
"C:\Program Files\MongoDB\Server\4.4\bin\mongod.exe" --config 
"C:\Program Files\MongoDB\Server\4.4\bin\mongod.cfg" --service

C:\Program Files\MongoDB\Server\4.4\bin\mongod.cfg이걸 메모장으로 열었을 때
dbPath가 실제 저장소의 위치 : C:\Program Files\MongoDB\Server\4.4\data

WiredTiger는 엔진 2개(쿼리용, 저장용?)를 이어주는 것 mysql에서 계승


4. 문서(Document = row)에 대한 정보 (내부적인 상태)
    --db.stats(1042); : 자료를 입력했을 때 mongoDriver가 동작된 후 데이터 상태 확인

자료를 입력 했을 때 MongoDriver가 어떻게 동작하는가
    1. MongoDB에 삽입되는 문서의 고유번호 ID인 _id로 필드와 값을 생성
    2. 문서를 MongoDB의 bson(binary json)으로 변환한다.
    3. 네트워크 소켓을 이용해서 데이터베이스를 전달

============================================================================<실습>
1. 서비스에서 mongo 서버를 중지

2. c:\data\mydata 폴더를 생성

3. c:\data\log\my.log 파일 생성
   c:\data\cfg\my.cfg 파일 생성

4. 해당 로그 파일을 저장할 때 사용자가 지정하는 특정 위치를 사용하도록 지정한다.
   c:\> echo logpath = "c:\data\log\my.log" > "c:\data\cfg\my.cfg"

5. db path를 지정한다. 서비스에 이름도 등록하자 <윈도우 서비스에서 등록확인>
   c:\> mongod --dbpath "c:\data\mydata" --logpath "c:\data\cfg\my.cfg" (한 줄로 이어서)
   --install --serviceName MyMongo --serviceDisplayName MyMongo

6. c:\> mongod --dbpath "c:\data\mydata" --logpath "c:\data\cfg\my.cfg" --remove

7. c:\>Net start MyMongo    c:\>Net stop MyMongo

============================================================================
테이블을 생성한 후 데이터를 입력해보자
[오라클]
CREATE TABLE MY(
    USER_ID VARCHAR2(20), AGE NUMBER, STATUS VARCHAR2(5)
);

INSERT INTO MY VALUES('AAA', 23, 'A');

[몽고]
테이블을 만들면서 값을 넣을 수도 있고 값만 넣어서 테이블을 만들 수도 있다.
ex1) 값을 넣어서 테이블을 만드는 방법
db.exam.insert({a:"a"})  ==> 생성하며 insert
db.exam.find()  ==> 생성 확인

ex2) 테이블을 생성하는 방법
db.createCollection("exam02");  ==> 생성, 특별히 인덱스를 주는 경우에만 씀
db.getCollectionNames()  ==> 생성 확인
db.exam02.stats()  ==> 상태, 정보확인
db.printCollectionStats()  ==> 상태, 정보확인

ex3) 위 오라클과 같은 생성
db.my.insert( {user_id:"AAA", age:23, status:"A"})
db.my.insert( {user_id:"BBB", age:40, staus:"B"},
                  {user_id:"CCC", age:32, staus:"C"},
                  {user_id:"DDD", age:28, staus:"D"},
                  {user_id:"EEE", age:30, staus:"E"},
                  {user_id:"FFF", age:36, staus:"F"} )

============================================================================1. nums 테이블을 만들어서 숫자를 입력해보자
db.nums.save({num:1000000})
db.nums.save({num:NumberInt(10000)})
db.nums.save({num:NumberLong(10000)})
db.nums.find()

https://bsonspec.org/spec.html에서 16진수타입을 보고 찾아라
2. int32 자료형을 찾아라
db.nums.find({num:{$type:16}})

3. int64 자료형을 찾아라
db.nums.find({num:{$type:18}})

4. double 자료형을 찾아라
db.nums.save({num : 98.9})
db.nums.find({num:{$type:1}})

5. new Date() 객체를 입력해보자
db.nums.save({num : new Date()})
db.nums.save({num : new Date() + 1})

6. typeof 객체의 타입을 확인해보자. date 객체를 찾아보자
typeof new Date()
db.nums.find({num:{$type:9}})
db.nums.find({num:{$type:2}})

============================================================================
save() : insert, update와 같은 뜻을 가지지만 insert, update는 특정 필드값을 수정 추가하는 구문이라면
          save는 내용 전체를 덮어쓰는 기능을 가진다.

          매개변수로 _id를 지정하지 않으면 insert 같은 뜻을 가지게 된다.
          매개변수로 _id를 전달되는 경우에는 있으면 덮어쓰고 없으면 새로 추가된다.

ex)
db.exam03.save( { item : "book", qty : 40 } )
db.exam03.find()
db.exam03.save( { _id : 1111, item : "book", qty : 40 } )  ==> id1111 없으니까 추가 됨
db.exam03.find()
db.exam03.save( { _id : 1111, item : "book", qty : 50 } )  ==> id1111 있으니까 수정 됨
db.exam03.find()

db.exam03.insert( { _id : 1111, item : "book", qty : 50 } )  ==> id1111 있으니까 insert 안됨
db.exam03.find()

============================================================================
Q1) MY 컬렉션의 전체 내용을 확인하자
db.my.find()    -->    select * from my;


Q2) MY에서 user_id, age, status 값을 리턴받자. 
db.my.find( { }, { user_id : 1, age : 1, status : 1 } );


Q3) Q2)의 결과에서 _id는 빼라
db.my.find( { }, { user_id : 1, age : 1, status : 1, _id : 0 } );    -->    select user_id, age, status from my;


Q4) age랑 user_id만 출력하자
db.my.find( { }, { age : 1, user_id : 1, _id : 0 } );


Q5) status 'A'인 문서만 리턴하자
select * from
my
where status = 'A';

db.my.find( { status : "A"} )


Q6) status 'A'인 문서에서 user_id, status 만 출력하자
db.my.find( { status : "A" }, { user_id : 1, status : 1, _id : 0 } ) 

select user_id, status from my where status = 'A';


Q7) user_id가 FFF인 status를 G로 변경해보자
db.my.updateOne(
{ user_id : "FFF" },
{ $set : { status : "G" } }
)


Q8) age가 40 이상인 데이터의 status를 K로 변경해보자
db.my.updateMany(
{ age : { $gte : 40 } },
{ $set : { status : "K" } }
)

db.my.update(
{ age : { $gte : 36 } },
{ $set : { status : "Z" } },
{ multi : true }
)

'데이터과학자 - 강의 > javascript & mongoDB' 카테고리의 다른 글

210615 MongoDB - aggregate, mongofiles  (0) 2021.06.15
210614 MongoDB - aggregate  (0) 2021.06.14
210611 MongoDB  (0) 2021.06.12
210609 javascript, MongoDB  (0) 2021.06.09
210608 javascript  (0) 2021.06.08

1. js Form 객체에 대해 이해

2. mongoDB 설치

 

============================================================================

JS Form 객체
    1. <form> 태그는 독립적으로 사용하지 않는다.
    2. <form> 태그 안에는 여러가지 입력 양식을 사용한다.
    3. DOM(Document Object Model)로 접근해서 제어한다.
    4. Form 객체를 액세스하여 제어한다.

JS Form 객체 속성
    action => 태그의 action과 동일하다.
    elements => 폼 태그안에 있는 양식(이너태그)을 배열로 관리
    length => 이너 태그의 개수를 리턴
    name => 태그의 name과 동일하다
    method => 태그의 method랑 동일하다
    target -> 태그의 target과 동일

JS Form 태그의 객체를 탐색 <form name='fm'><input type='text' name='id' /></form>
    1. document.fm.id.value (!= document.fm.name)
    2. document.forms[0].elements[0].value
    3. document.forms['fm'].elements['id'].value
    4. document.forms['fm']['id'].value

 

============================================================================

1. MongoDB 홈페이지에서 Community Server 다운

    https://www.mongodb.com/try/download/community

 

사용가능한 버전과 플랫폼인지 확인

2. 다운받은 후 기본 경로로 설치(재설치하기엔 너무 오래걸려서 캡쳐가 없음....)

 

3. 환경변수에 MongoDB가 설치된 경로 추가

환경 변수 편집하는 방법은 java설치 시 했으니까 패스

 

4. 실행확인

종료하면 쿨하게 bye라고 쳐준다

============================================================================

본격적인 수업은 내일부터라 오늘 흘러가며 들었던 내용들(정돈 안돼있음)

  - join이 없다

  - Replica Sets랑 Sharded Clusters가 몽고디비의 핵심이다.

  - config 서버는 router 기능을 가지고 있다.
  - 몽고에서 메모리 분할단위인 Chunks 가 중요하다.

  - MongoDB의 인덱스는 oracle의 인덱스와는 다르게 Shard 분산시에 필요하다.

 

MongoDB의 Grouping은 3가지 방법

  1. 일반적인 집계함수

  2. Aggregation 객체를 이용(파이프라인?)

  3. 자바스크립트 코드를 작성

 

SQL과의 용어비교

 

SQL과의 구문비교

'데이터과학자 - 강의 > javascript & mongoDB' 카테고리의 다른 글

210615 MongoDB - aggregate, mongofiles  (0) 2021.06.15
210614 MongoDB - aggregate  (0) 2021.06.14
210611 MongoDB  (0) 2021.06.12
210610 MongoDB  (0) 2021.06.10
210608 javascript  (0) 2021.06.08

0608 자바스크립트
mongoDB는 js를 사용하기 때문에 실전압축으로 javascript에 대해 배운다.

파이썬과 비슷한 부분은 넘어가거나 차이만 설명

 

============================================================================

javascript 
장점
  - 작업이 빠르고 생산성이 좋음
  - 운영체제에 대한 제한을 받지 않음
단점
  - 소스코드가 노출됨
  - 한정된 객체와 메소드

자바스크립트 태그
[형식]
<script language="

============================================================================

배열 : 하나 이상의 상수를 나열해서 하나의 이름으로 등록해서 사용하는 참조형으로
      요소를 인덱스로 관리하며 0부터 시작한다. 
      length 속성을 가진다. 

[형식] 
      user_name = new Array(요소..... | 배열의 크기);
ex)
      var arr = new Array(10, 20, 30, 40, "abc");
      
      join() : 배열을 하나의 문자열로 만든다 
      reverse() : 역순으로
      sort() : 정렬
      slice() : 배열의 일부를 선택해서 부분적인 새로운 배열을 생성한다
      concat() : 두 개의 배열을 하나의 배열로 만든다.
      
============================================================================

함수 : 프로그램내에서 특정 작업 수행을 위해 독립적으로 만들어진 하나의 단위
      <head> ~ </head> 태그 사이에 function으로 시작{ }
      
[형식] 
      function user_name(arguments) {
          명령;
      }
      
      user_name(arg_values);
      
============================================================================

자주 사용하는 내장함수
      eval(String) : String을 자바스크립트 코드로 실행
      isFinite(Number) : 무한값의 유무
      inNan(Number) : NaN 뮤ㅜ
      parseInt(String, 진수) : String을 해당 진수의 정수로 변환
      parseFloat(String) : String을 유리수로 변환
      escape() : 인코딩 변환
      unescape() : 디코딩 변환
      encodeURI(uri) : 최소한의 문자만 인코딩
      decodeURI(encodeURI) : 최소한의 문자만 디코딩

 

============================================================================

내장 객체
Date
      setYear() : 1970년도 이상의 년도를 설정  / getYear()  / getFullYear()
      setMonth() : 0 = 1월
      setDate() : 날짜를 설정
      setDay() : 요일을 설정 0 = 일요일
      setTime() : 1970년 1월 1일 이후 시간을 1/1000으로 나타낸 값
      setHours() : 시간
      setMinutes() : 분
      setSeconds() : 초

============================================================================

객체 = property + message
인스턴스 객체 = new 를 이용한 생성된 객체

[형식]
      function user_name(args) {
      this.이름 = args;
      }

      객체 이름 = new user_name(args);

      for in : 하나 이상의 나열형 값을 가진 객체의 배열 형식을 표시할 때 사용
      with : 객체에 포함된 속성이나 메소드를 여러번 사용할 때 with문으로 객체를 한 번 선언한 후 with문 안에서 객체를 생략하고
             속성이나 메소드명만 가지고 사용한다.
      typeof null

============================================================================

JS DOM(Document Object Model)
      HTML, XML 문서에 대한 프로그래밍 인터페이스
      객체지향 모델로써 구조화된 문서를 표현하는 형식
      플랫폼 / 언어 중립적으로 구조화된 문서를 표현하는 w3c의 공식 표준
      https://dom.spec.whatwg.org/     -- 4.4, 4.5, 4.9
      https://www.w3.org/DOM/DOMTR
      
      1. document : DOM의 최고 상위 객체, html 문서
      2. element : html 문서에 사용되는 모든 태그, 요소
      3. attribute : 엘리먼트가 가진 속성
      4. node : 객체를 지칭, 요소, 속성, 텍스트 등을 말한다.
       4-1. nodeName : 노드의 이름을 리턴, 텍스트 노드 #text
       4-2. nodeType : 노드의 유형을 정수로 리턴(1: 요소, 2: 속성, 3: 텍스트, 8: 주석)
       4-3. childNodes : 노드의 자식노드 노드리스트(배열)
       4-4. firstChild : 노드의 첫 번째 자식 노드를 리턴
       4-5. lastChild : 노드의 마지막 자식 노드를 리턴
       4-6. previousSibling : 노드의 이전 위치를 자리한 형제 노드를 리턴
       4-7. nextSibling : 노드의 다음 위치에 자리한 형제 노드를 리턴 
       4-8. parentNodee : 노드의 부모노드를 리턴


============================================================================

'데이터과학자 - 강의 > javascript & mongoDB' 카테고리의 다른 글

210615 MongoDB - aggregate, mongofiles  (0) 2021.06.15
210614 MongoDB - aggregate  (0) 2021.06.14
210611 MongoDB  (0) 2021.06.12
210610 MongoDB  (0) 2021.06.10
210609 javascript, MongoDB  (0) 2021.06.09

+ Recent posts