wisePocket

[Database] Oracle과 MongoDB 비교 CRUD 복기 본문

(old)Java Backend study

[Database] Oracle과 MongoDB 비교 CRUD 복기

ohnyong 2023. 7. 5. 18:41

MongoDB는 BSON으로 데이터가 쌓이기 때문에 Array 데이터나 Nested한 데이터를 쉽게 넣을 수 있는 특징이 있다.

 

우선 Oracle을 주로 사용했기 때문에 햇갈리는 부분이 많다.

MongoDB의 DB계층구조 부터 Oracle과 비교해서 개념을 정리했다.

SQL문은 대체로 유사한데 비교하여 주석하면서 테스트했다.

 

db = 데이터베이스는 컬렉션의 물리적 컨테이너. 하나의 데이터베이스에는 보통 여러개의 컬렉션을 가질 수 있다.

user = collection이다. Document 의 그룹이며 RDBMS Oracle의 예를 들면 Table 과 같은 개념

         +- collection 내에 Document 는 하나의 키(key) 와 값(value)의 집합이다.

Oracle  MongoDB
 Database  Database
 Table  Collection
 Tuple/Row/Record  Document
 Column  Field
 Table Join  Embedded Documents
 Primary Key  Primary Key ( Default _id )

이와 같은 개념에서부터 CRUD SQL문을 이해해야 한다.

예로 db.users.insert_one({ aaa:bbb }) 문의 경우

"aaa라는 key값에 bbb라는 value값을 가진 Field를,

users라는 collection(table)에 넣어라. => db라는 큰 틀에서"

라는 의미로 해석될 수 있다.

 

 

MongoDB의 Collection 생성부터 CRUD문을 복습

0. Collection(==Table) 생성과 삭제 관련

db
//mydb 데이터베이스 생성
use mydb
db

show dbs

//mydb 에 collection( ==TABLE) 을 생성해보자
db.createCollection("employees",{capped:true,size:10000})
//capped:true ==> 저장공간이 차면 기존 공간을 재사용하겠다는 설정
//삭제
db.employees.drop()

db
show collections
show dbs
//조회
db.employees.find()

db.employees.isCapped()

db.employees.stats();

db.employees.renameCollection("emp")

show collections

//컬렉션 삭제 db.컬렉션이름.drop()
db.emp.drop()
show collections


//capped 옵션 살펴보기
//컬렉션 생성
db.createCollection("cappedCollection", {capped:true,size:10000})
//capped:true => 최초 제한된 크기로 생성된 공간에서만 데이터를 저장하는 설정
//size:10000 ==> 10000보다는 크고 가장가까운 256배수로 maxsize가 설정 된다
show collections
db.cappedCollection.find()
db.cappedCollection.stats()

//도큐먼트(==row)를 size 초과하도록 반복문 이용해서 넣어보자.
for(i=0;i<1000;i++){
     db.cappedCollection.insertOne({x:i})   
}

db.cappedCollection.find()
db.cappedCollection.find().count()
//처음 넣었던 데이터들이 사라진 것을 확인 할 수 있다.
db.cappedCollection.isCapped()
//==============================================

Collection을 생성, 삭제 하는 것 부터 시작

Collection == Table로 추후 프로젝트 DB설계에서 DB Diagram을 설계 할 때 요소들의 그룹 이름이 될 부분이다.

 

1. (C)RUD:Create == Insert

/*[1] Create :
        - insertOne({}) : 한 개의 document 생성
        - insertMany([{}, {}, {}, ...]) : 여러 개의 document 생성
           db.emp.insertOne({ <----- collection (table)
                  id: 'a001', <----- field ----+ (column) +
                  name:'James',<---- field ----+ (column) +--------- document (record)
                  dept:'Sales' <---- field ----+ (column) +
           })
*/
use mydb
db.createCollection('member')
show collections

db.member.find()
db.getCollection('member').find()
db.member.insertOne({
    name:'김민준',
    userid:'min',
    tel:'010-2920-2020',
    age:20
})
db.member.find()

/*
_id 필드가 자동으로 생성된다. document의 유일성을 보장하는 키
    전체 : 12 byte
        ____ 4byte : 현재 timestamp => 문서 생성 시점
        ___  3byte : machine id
        __   2byte : mongoDB 프로세스 id
        ___  3byte : 일련번호
*/

db.member.insertOne({
    _id:1,
    name:'홍길동',
    userid:'hong',
    tel:'011-2020-3131',
    age:22
})
db.member.find()

//document를 bson으로 반환하여 mongoDB에 저장
//_id : primary key같은 기능으로 자동으로 index가 생성된다. ==> 검색을 빠르게 할 수 있다.


//다중 도큐먼트 레코드를 저장해보자
db.member.insertMany([
    {name:'이민수', userid:'Lee', age:23},
    {name:'홍길동', userid:'Hong', tel:'010-2020-0313', age:24},
    {name:'최민자', userid:'Choi', tel:'011-5510-5313', age:25},
])
db.member.find()

db.member.insertOne({name:'표진우', userid:'Pyo', passwd:'123', grade:'A'})

db.user.insertMany([
    {_id:3, name:'김철', userid:'kim1', passwd:'1111'},
    {_id:2, name:'최철', userid:'choi1', passwd:'1111'},
    {_id:5, name:'김철', userid:'kim1', passwd:'1111'}   
], {ordered:false})
//ordered 옵션 : 기본값 true, 순서대로 insert 할지 여부 지정.
//false를 주면 순서대로 입력하지 않음.
db.user.find()

/*
[실습1]---------------------------------------------------------------------
1. boardDB생성
2. board 컬렉션 생성
3. board 컬렉션에 name 필드값으로 "자유게시판"을 넣어본다
4. article 컬렉션을 만들어 document들을 삽입하되,
   bid필드에 3에서 만든 board컬렉션 자유게시판의 _id값이 참조되도록 처리해보자.

5. 똑 같은 방법으로 "공지사항게시판"을 만들고 그 안에 공지사항 글을 작성하자.
--------------------------------------------------------------------------
*/

use boardDB
db
db.board.drop()
db.article.drop()

freeboard_res=db.board.insertOne({name:'자유게시판'})
//freeboard_res에는 자유게시판의 도큐먼트의 _id값이 담긴다. 
freeboard_id=freeboard_res.insertedId

db.article.insertMany([
    {bid:freeboard_id, title:'자유게시판 첫번째 글', content:'안녕하세요', writer:'kim'},
    {bid:freeboard_id, title:'자유게시판 2번째 글', content:'반가워요', writer:'hong'},
    {bid:freeboard_id, title:'자유게시판 3번째 글', content:'mongoDB', writer:'choi'}
])

db.article.find()

notice_res=db.board.insertOne({name:'공지사항'})
notice_id=notice_res.insertedId

db.notice.insertMany([
    {bid:notice_id, title:'공지 첫번째 글', content:'[공지]안녕하세요', writer:'kim'},
    {bid:notice_id, title:'공지 2번째 글', content:'[공지]반가워요', writer:'hong'},
    {bid:notice_id, title:'공지 3번째 글', content:'[공지]mongoDB', writer:'choi'}
])

db.article.find()
db.notice.find()


var empArr=[
        {
                "empno" : "7499",
                "ename" : "ALLEN",
                "job" : "SALESMAN",
                "mgr" : "7698",
                "hiredate" : "1981-02-20",
                "sal" : "1600.00",
                "comm" : "300.00",
                "deptno" : "30"
        },
        {
                "empno" : "7521",
                "ename" : "WARD",
                "job" : "SALESMAN",
                "mgr" : "7698",
                "hiredate" : "1981-02-22",
                "sal" : "1250.00",
                "comm" : "500.00",
                "deptno" : "30"
        },
        {
                "empno" : "7654",
                "ename" : "MARTIN",
                "job" : "SALESMAN",
                "mgr" : "7698",
                "hiredate" : "1981-09-28",
                "sal" : "1250.00",
                "comm" : "1400.00",
                "deptno" : "30"
        },
        {
                "empno" : "7844",
                "ename" : "TURNER",
                "job" : "SALESMAN",
                "mgr" : "7698",
                "hiredate" : "1981-09-08",
                "sal" : "1500.00",
                "comm" : "0.00",
                "deptno" : "30"
              },

{"empno":7369, "ename":"SMITH","job":"CLERK",mgr:7902,"hiredate" : "1980-12-17","sal":800.0, "comm" : "0.00","deptno":20},
{"empno":7566, "ename":"JONES","job":"MANAGER",mgr:7839,"hiredate" : "1981-04-02","sal":2975.0, "comm" : "0.00","deptno":20.0},
{"empno":7782,"ename":"CLARK","job":"MANAGER",mgr:7839,"hiredate" : "1981-09-08","sal":2450.0, "comm" : "0.00","deptno":10.0},
{"empno":7934,"ename":"MILLER","job":"CLERK",mgr:7782,"hiredate" : "1981-09-08","sal":1300.0, "comm" : "0.00","deptno":10.0},
{"empno":7788,"ename":"SCOTT","job":"ANALYST",mgr:7566,"hiredate" : "1982-12-09","sal":3000.0, "comm" : "0.00","deptno":10.0},
{"empno":7839,"ename":"KING","job":"PRESIDENT","hiredate" : "1981-11-17","sal":5000.0, "comm" : "0.00","deptno":10.0},
{"empno":7876,"ename":"ADAMS","job":"CLERK",mgr:7788,"hiredate" : "1983-01-12","sal":1100.0, "comm" : "0.00","deptno":20.0},
{"empno":7902,"ename":"FORD","job":"ANALYST",mgr:7566,"hiredate" : "1981-12-03","sal":3000.0, "comm" : "0.00","deptno":20.0},
{"empno":7934,"ename":"MILLER","job":"CLERK",mgr:7782,"hiredate" : "1982-01-23","sal":1300.0, "comm" : "0.00","deptno":10.0}
]
db.emp.insertMany(empArr)

var deptArr=[{
                "deptno" : "10",
                "dname" : "ACCOUNTING",
                "loc" : "NEW YORK"
        },
        {
                "deptno" : "20",
                "dname" : "RESEARCH",
                "loc" : "DALLAS"
        },
        {
                "deptno" : "30",
                "dname" : "SALES",
                "loc" : "CHICAGO"
        },
        {
                "deptno" : "40",
                "dname" : "OPERATIONS",
                "loc" : "BOSTON"
        }
  ]
db.dept.insertMany(deptArr)

강의에서는

insert_one({"a":"1", "b":"2"})만 사용되었지만

insertMany==pymongo에선 insert_many()도 사용 될 것 같다.

db.collection.insert_many([

     { "a":"1", "b":"2"},

     { "a":"3", "b":"4"}

])

 

한번에 입력하는 것 외에 사실 큰 차이는 없다. <- 성능차이, 코드정리 차이는 있다.

 

2. C(R)UD:Read == Find

/*
R : read 조회
    - findOne() : 매칭되는 1개의 document를 조회
    - find() : 매칭되는 여러개의 document list를 조회
    find({조건들==where절같은..},{필드들==select할것들..})

*/
use mydb
db.member.find({})
//select * from member
arr=db.member.find().toArray()
arr[0]
arr[1]

db.member.find()
//member 에서 name, tel 만 조회하고 싶다면
db.member.find({},{name:true, tel:true, _id:false})
//select name, tel from member
db.member.find({}, {name:1, tel:1, _id:0})
//위 문장과 동일함, true=1, false=0 으로 변경가능

//oracle과 양식이 반대라 생각하면 됨.

//조건절
//select * from member where age=23
db.member.find({age:23},{})

//select name, userid, age from member where age=22
db.member.find({age:22},{name:1, userid:1, age:1})

//userid 가 'hong'이고 age:22인 회원 정보
db.member.find({userid:'hong',age:22},{})

//age가 22이거나 userid가 'hong'인 회원정보
db.member.find({$or:[{age:22},{userid:'hong'}]},{})
//select * from member where age=22 or userid='hong'
//논리연산
//$or : 배열 안 두개 이상의 조건 중 하나라도 참인 경우를 반환
//$and: 배열 안 두개 이상의 조건이 모두 참인 경우를 반환 
//$nor: $or의 반대 

db.member.find()
//<1> userid가 'Choi'인 회원의 name, userid, tel만 가져오기
db.member.find({userid:'Choi'},{name:1, userid:1, tel:1, _idx:0})
//<2> age가 24세이거나 userid가 Lee인 회원 정보 가져오기
db.member.find({$or:[{age:24},{userid:'Lee'}]})

//<3> name이 이민수이면서 나이가 23인 회원 정보 
db.member.find({$and:[{name:'이민수'},{age:23}]})


/*
[실습2]
1. emp Collection 생성 {capped:true, size:100000} Capped Collection, size는 100000 으로 생성
2. scott계정의 emp레코드를 mydb의 emp Document 데이터로 넣기 
  => insertOne()으로 3개 문서 삽입, 
     insertMany로 나머지 문서 삽입해보기
*/

db.emp.find()
db.dept.find()

db.emp.find({empno:7788},{ename:1, empno:1, job:1, _id:0})
//emp에서 사원의 이름과 급여를 가져와 보여주세요
db.emp.find({}, {ename:1, sal:1})
//emp에서 job이 'SALESMAN'이거나 급여가 3000인 사원 정보를 보여주세요
db.emp.find({$or:[{job:'SALESMAN'}, {sal:3000}]}, {})
//반대 
db.emp.find({$nor:[{job:'SALESMAN'}, {sal:3000}]}, {})

/* 비교 문법 
$gt     >    
$gte    >=   
$in          목록 중의 어느 하나라도 있는지 여부를 체크
$lt     <    
$lte    <=   
$ne     !=   not equal
$nin         $in의 반대. not in
*/

//member에서 age가 20세를 초과하는 회원의 이름, 나이를 출력
db.member.find({age:{$gt:20}},{name:1, age:1})

//emp에서 급여가 3000이상인 사원의 사번,이름,업무,급여
db.emp.find({sal:{$gte:3000}},{empno:1, ename:1, job:1, sal:1})
//emp에서 급여가 1300 ~ 2000사이의 이름, 업무, 급여, 부서번호
//select ename,job,sal,deptno from emp where sal >=1300 and sal <2000;
db.emp.find({$and:[{sal:{$gte:1300}},{sal:{$lte:2600}}]} , {ename:1, job:1, sal:1, deptno:1})
db.emp.find({sal:{$gte:1300, $lte:2600}}, {ename:1, job:1, sal:1, deptno:1})
//emp에서 담당 업무가 'MANAGER'인 사원의 사번,이름,업무를 보여주세요
db.emp.find({job:'MANAGER'}, {empno:1, ename:1, job:1})
//emp에서 사원번호가 7369,7654,7934인 사원의 사원번호,
//	이름,업무,급여를 출력하세요.
db.emp.find({empno:{$in:[7369,7654,7934]}},{empno:1, ename:1, job:1, sal:1})
//20번 부서인 사원의 이름,업무,부서번호를 출력하세요
db.emp.find({deptno:20},{ename:1, job:1, dpetno:1})

db.emp.find()


//부서번호가 20번이 아닌 사원의 모든 정보를 출력하세요
db.emp.find({deptno:{$ne:20}},{})

//업무가 CLERK이거나 ANALYST인 사원의 모든 정보를 출력하세요
db.emp.find({job:{$in:['CLERK','ANALYST']}},{})

//업무가 CLERK 또는 ANALYST가 아닌 사원의 모든 정보를 출력하세요
db.emp.find({job:{$nin:['CLERK','ANALYST']}},{})

//sql문의 like절==> 정규식을 이용한다
//ename이 KING인 사원의 모든 정보를 출력하세요
db.emp.find({ename:{$regex:/^K/}})

//select * from emp where like '%S'
db.emp.find({ename:/S/})

//member의 userid중 'o'가들어가는 회원정보 출력
db.member.find({userid:/o/})

/*
<1>member에서 회원의 나이를 내림차순으로 정렬하고, 
  같은 나이일 때는 이름 가나다순으로 정렬해서 출력하세요
  */
db.member . find() .sort({age:-1,name: -1})
  /*
<2> emp에서 부서번호로 정렬한 후 부서번호가 같을 경우
*/
db. emp. find({}, {empno: 1, ename: 1, deptno:1, sal:1}) .sort({deptno:1, sal:-1})
/*
<3> emp에서 부서번호가 10,20인 사원의 이름,부서번호,업무를 출력하되
    이름 순으로 정렬하시오
*/
db.emp. find ({deptno: {$in: [10, 20]}}, {ename: 1, deptno: 1, job:1}) .sort ({ename: 1})
//전체 사원수를 보여주세요
db.emp.find().count ()
//select count (*) from emp
db.member.find()
//member에서 연락처를 가지고 있는 회원정보를 보여주세요
db.member.find({tel:{$exists:true}})
db.member.find({tel:{$exists:true}}).count ()
//select count(tel) from member
db.member.find({tel: {$exists: 0}})
// select * from member where tel is null


//member에서 나이가 23세 이상인 회원이 몇명인지 보여주세요
db.member.find({age:{$gte:23}}).count ()

//distinct
db.emp.distinct ("deptno").length
//select distinct (deptno) from emp
//emp의 업무 종류를 출력하세요
db.emp.distinct('job')
db.emp.distinct ('job'). length

/*
<1> employees에서 30번 부서의 사원수를 출력하시오.
<2> employees에서 보너스(comm)을 받는 사원의 수를 출력하시오
<3> 직업이 SALESMAN이면서 보너스를 100이상 받는 사원수를 출력하시오
*/

db.emp.find( {deptno: '30'}) .count ()
db.emp.find({comm: {$exists:1}})
db.emp.find({comm: {$gt: '0.00'}}, {})
db.emp.find ({comm: {$ne: '0.00'}}).count ()
db.emp. find({$and: [ {job: 'SALESMAN'}, {comm: {$gte: '100.00'}}]}). count ()

//내장형 문서 조회- Embeded Document
db.products.insertMany([
{item: 'journal', qty:25, size:{h:14, W:21, uom: 'cm'}, status: 'A'},

{item: 'notebook', qty:50, size: {h:8.5, w:11, um: 'in'}, status: 'A'},
{item: 'paper', qty: 100, size:{h:10, w:13, uom: 'in'}, status: 'D'},
{item: 'planner', qty:75, size:{h:22.85, w:30, uom: 'cm'}, status: 'C'},
{item:'postcard', qty:45, size:{h:10, w:15.25, uom:'cm'}, status: 'B'},
])
db.products.find()

//size가 h:8.5, w:11, uom:'in' 인 상품을 조회해서 출력하세요
db. products. find({size: {h: 8.5,W: 11, uom: ' in' }})
//size중  h가 10이상인 상품만 가져와 출력하세요
db.products.find({size:{h:{$gte:10}}}) //===> 결과가 나오지 않음
db.products.find({'size.h':{$gte:10}}).count()

//단위가 cm인 상품만 가져와 출력하기
db.products.find({"size.uom":"cm"})
//size.h가 10미만이고 status가 A인 것들만 가져오기

db.inventory.insertMany([
	{ item: "journal", qty: 25, tags: ["blank", "red"], dim_cm: [ 14, 21 ] },
	 { item: "notebook", qty: 50, tags: ["red", "blank"], dim_cm: [ 14, 21 ] },
	 { item: "paper", qty: 100, tags: ["red", "blank", "plain"], dim_cm: [ 14, 21 ] },
	 { item: "planner", qty: 75, tags: ["blank", "red"], dim_cm: [ 22.85, 30 ] },
	 { item: "postcard", qty: 45, tags: ["blue"], dim_cm: [ 10, 15.25 ] } 
	 ]);
	 
	 /*
배열 선택자
$all: 주어진 조건의 모든 요소를 포함하는 배열
$elemMatch: 주어진 조건의 모든 요소와 일치하는 배열
$size: 주어진 크기 조건과 일치하는 배열
*/

//tags 필드에 red, bLank 값만 배열에 가지고 있는 상품을 조회하세요
db.inventory.find()

db.inventory.find({tags:['red', 'blank']})
//'red', 'blank' 만 가지고 있는 경우만 출력된다

db.inventory.find({tags: 'red' })
//' red'를 포함하는 모든 문서를 가져온다

//dim cm 필드에 25이상의 값이 포함된 상품을  가져와 출력하세요
db.inventory.find({dim_cm:{$gte:25}})

//tags 중에서 배열크기가 2인 상품을 출력하세요
//$size
db.inventory.find({tags: {$size:2}})

//find()로 조회한 결과는 cursor형태의 객체로 반환된다
var mycr=db.emp.find ()
while (mycr.hasNext ()){
printjson(mycr.next ())
}
//부서번호가 20번인 부서의 사원정보를 커서를 이용해서 출력하세
db.emp.find({deptno:20})
var cr=db.emp.find ({deptno: 20})
//forEach()함수 이용
cr. forEach (printjson)

//emp에서 급여가 높은순으로 정렬해서 3명만 출력하세요
db.member.find ({}).sort ({age:-1}).limit(3)

use mydb
show collections
db.inventory.find()

db.inventory.find({tags:'blank'})
db.inventory.find({tags:['blank','red']})
db.inventory.find({tags:{$all:['blank','red']}})
db.inventory.find({tags:{$size:1}})
//dim_cm 중 인덱스가 1번째인 값이 25보다 작은 상품들을 조회해서 출력하세요
db.inventory.find({"dim_cm.1":{$lt:25}})

Oracle에서 계속해서 DB를 확인 할 때 사용했던

select * from members;

와 같은 표현이 

db.members.find({})

이다.

 

그 외

  • 조건절 select * from members where aaa; 로 필터링하여 조회
  • 논리연산 (true or false)의 조건에 맞는 대상을 조회
  • 비교문법 의 조건에 맞는 대상을 조회

등 추가적인 sql문의 응용이 필요하면 위 복습자료를 먼저 참고하고 테스트 후 해결이 안될 때 그 외 레퍼런스를 찾아보자.

 

DB에서 원하는 정보를 추려서 가져오는 것이 생각보다 중요해서 외우기보다는 "어떤 상황에 이런것이 필요하겠다." 라고 감을 잡고 있어야 하지 않을까?

 

3. CR(U)D:Update == Update

//#[3] Update 
/* - updateOne({}): 특정 필드 값을 변경하거나, 증가,감소 시킬 때
   - updateMany({}): 
   - replaceOne({조건절},{대체할문서},{옵션}) : 도큐먼트 대체   
*/
db.user.find()
db.user.replaceOne({userid:'choi1'},{'name':'최철수',userid:'choi2',passwd:'3333'})
db.user.replaceOne({userid:'hong'},{name:'홍길동',userid:'hong1', passwd:'1234'},{upsert:true})
//upsert옵션을 주면 조건에 해당하는 문서가 있으면 수정하고, 없으면 삽입한다.

db.user.updateOne({userid:'hong1'},{$set:{passwd:'abcd'}})
db.user.replaceOne({userid:'hong1'},{passwd:'1234'},{upsert:true})
db.user.find()
//passwd가 '1234'객체에 userid와 name값을 설정하세요
db.user.updateOne({passwd:'1234'},{$set:{userid:'hong',name:'홍길동'}})
/*도큐먼트 수정 연산자
  $set : 필드값 수정값으로 설정
  $inc : 필드값을 증가시키거나 감소시킨다.
          $inc:{age:1}, $inc:{age:-2}
  $mul : 필드값에 곱하기를 수행한다
  $min : 필드값이 주어진 값보다 클 경우 새 값으로 교체한다.
  $max : 필드값이 주어진 값보다 작을 경우 새 값으로 교체한다
  $currentDate: 필드값을 현재 날짜로 수정  (Date-디폴트, Timestamp)
    Timestamp를 사용하려면 $type연산자를 사용해야 한다
  $unset: 해당 필드를 제거한다. 
  $rename: 필드명을 변경한다 
*/
db.member.find()
//userid가 'min'인 사람의 나이를 1 증가시키세요
db.member.updateOne({userid:'min'},{$inc:{age:1}})

//모든 회원에 grade필드를 추가하고 'A' 값을 주세요
db.member.updateMany({},{$set:{grade:'A'}})
db.member.find()

//member에서 나이가 22세 이상인 회원의 등급을 'B'등급으로 수정하세요
db.member.updateMany({age:{$gte:22}},{$set:{grade:'B'}})

db.member.updateMany({grade:'A'},{$mul:{age:2}})

db.member.updateMany({grade:'A'},{$min:{age:20}})
//grade가 'A'인 회원들의 나이가 20세보다 크면 20세로 수정한다.
db.member.find()
db.member.updateMany({grade:'A'},{$min:{age:30}})

db.member.find()
//userid가 'Lee'인 회원을 찾아서 30세 이하면 30세로 수정하세요
db.member.updateOne({userid:'Lee'},{$max:{age:30}})

//member컬렉션에 가입한 날짜를 indate라는 필드로 현재 날짜로 추가하세요
db.member.updateMany({},{$currentDate:{indate:true}})
db.member.updateMany({},{$currentDate:{indate2:{$type:'timestamp'}}})
db.member.find()

//member컬렉션에서 indate2를 제거하세요 => $unset
db.member.updateMany({},{$unset:{indate2:''}})

//tel필드명을 'phone'으로 변경하세요
db.member.updateMany({},{$rename:{tel:'phone'}})

// #배열 수정
/*
db.collection.updateMany({선택조건},
		{<update연산자>:{"<array>.$[<identifier>]":value}},
		{arrayFilters:[{<identifier>:<condition>}]}
		);
*/
db.inventory.find({item:'paper'})
//item이 paper인 상품의 tags배열에 있는 값 중에 'blank'의 값을 'blue'로 변경하세요
db.inventory.updateMany({item:'paper'},{$set:{"tags.$[tagE]":'blue'}},{arrayFilters:[{tagE:'blank'}]})

//item이 postcard인 상품의 dim_cm에 있는 값 중에 10인 값을 12로 수정하세요
db.inventory.updateMany({item:'postcard'},{$set:{"dim_cm.$[dimE]":12}},{arrayFilters:[{dimE:10.0}]})
db.inventory.find({item:'postcard'})

/*--배열 수정 연산자---------------------
[1] $addToSet : 배열에 해당 요소가 없으면 추가하고, 있으면 아무것도 하지 않음 
[2] $pop : 배열에서 맨앞 또는 맨뒤를 꺼낸다. shift, pop을 합쳐놓은 연산자
            {$pop:{필드:1, 필드2:-1}}  -1값=>shift기능, +1=>pop기능
[3] $pull : 배열에서 조건을 만족하는 특정 요소 하나를 제거한다.
            {$pull:{필드:조건1, 필드:조건2,...}}            
[4] $pullAll: {$pullAll:{필드:[값1, 값2,...]}}

[5] $push : 배열에 새 요소를 추가함
            {$push:{필드:값}} 
            배열을 push할 경우 배열 안의 배열로 추가된다 <== 조심
            각각 따로 push하고 싶다면
            {$push:{필드:{$each: 배열}}}          
*/
db.inventory.find()
db.inventory.updateMany({item:'journal'},{$addToSet:{tags:'gold'}})

//item이 'journal'인 상품의 tags에서 'blank'를 삭제하세요 
db.inventory.updateMany({item:'journal'},{$pop:{tags:-1}})
db.inventory.updateMany({item:'journal'},{$pop:{tags:1}})

//item이 'paper'인 상품의 tags에서 'blue'를 삭제하세요
db.inventory.updateMany({item:'paper'},{$pull:{tags:'blue'}})
db.inventory.find({item:'paper'})

//item이 'paper'인 상품의 tags에서 'skyblue'를 추가하세요
db.inventory.updateMany({item:'paper'},{$push:{tags:'skyblue'}})

db.inventory.updateMany({item:'paper'},{$pullAll:{tags:['red','skyblue']}})

db.inventory.updateMany({item:'paper'},{$push:{tags:['yellow','pink']}})

db.inventory.find({item:'journal'})

db.inventory.updateMany({item:'paper'},{$push:{tags:['yellow','pink']}})
db.inventory.updateMany({item:'journal'},{$push:{tags:{$each:['yellow','pink']}}})

insert와 마찬가지로

Update_one

Update_many

가 사용 될 예정이다.

도큐먼트를 수정하는 연산자, 배열 수정 연산자 내용도 추후 필요시 참고 할 예정

 

 

4. CRU(D):Delete == delete

// # [4] Delete 
//  - deleteOne()
//  - deleteMany()
db.member.find()
db.member.deleteMany({age:20})
db.member.deleteOne({grade:'B'})

//inventory에서 수량이 30개 미만인 상품을 삭제하세요
db.inventory.find()
db.inventory.deleteMany({qty:{$lt:30}})

use boardDB
/*
------------------------------------------------------------------
[실습]
use boardDB
1. boardDB에서 작업한다
2. 자유게시판에 아무 글이나 2~3개 작성한다. 특히 그 중에 글 하나에는 
    댓글 하나가 달린 상태로 생성해본다. 댓글은 comment필드에 배열로 넣는다. comment[{},{}]
3. 비밀게시판을 생성한다.
4. 비밀게시판에 작성자가 'noname'값을 가지는 글을 하나 작성한다.
5. 모든 글에 추천수 필드(upvote)를 추가하고 값을 0으로 설정한다
6. 비밀게시판 글에 추천수를 1 증가시킨다
7. 이미 댓글이 달린 자유게시판 글에 upvote 필드 없이 댓글을 추가한다.
8. 이미 댓글이 달린 글에 방금 달은 댓글에(특징을 기억해서 수정하자) 
    upvote 필드 값을 0으로 추가한다
==>배열요소값 수정 arraysFilters 파라미터 사용해보기.
------------------------------------------------------------------
*/
db.board.find()
db.article.find()

delete문은 자체는 어려움이 없어보여도 추가 부분인

특히 조건절, 비교연산 등을 주의깊게 사용해야 한다.

예로 계정을 잘못삭제 또는 모든게 삭제되면 치명적..

제일 쉽고 짧아보여도 주의해야 하는 부분.

 

5. 추가 응용 실습 자료

/*------------------------------------------------------------------
[실습]
use boardDB
1. boardDB에서 작업한다
2. 자유게시판에 아무 글이나 2~3개 작성한다. 특히 그 중에 글 하나에는 
    댓글 하나가 달린 상태로 생성해본다. 댓글은 comment필드에 배열로 넣는다. comment[{},{}]
3. 비밀게시판을 생성한다.
4. 비밀게시판에 작성자가 'noname'값을 가지는 글을 하나 작성한다.
5. 모든 글에 추천수 필드(upvote)를 추가하고 값을 0으로 설정한다
6. 비밀게시판 글에 추천수를 1 증가시킨다
7. 이미 댓글이 달린 자유게시판 글에 upvote 필드 없이 댓글을 추가한다.
8. 이미 댓글이 달린 글에 방금 달은 댓글에(특징을 기억해서 수정하자) 
    upvote 필드 값을 0으로 추가한다
==>배열요소값 수정 arraysFilters 파라미터 사용해보기.
------------------------------------------------------------------*/
use boardDB

db.board.find()
freeboard_id=db.board.find({name:'자유게시판'}).toArray()[0]._id
freeboard_id
db.article.find()

db.article.insertOne(
{bid:freeboard_id,title:'오늘은 즐거운 불금입니다',content:'좋은 시간 되세요',writer:'김해피'}
)

db.article.insertOne(
{bid:freeboard_id,title:'내일은 즐거운 주말입니다',content:'역시 좋은 시간 되세요',writer:'박해피',
    comment:[
        {writer:'김대댓',cotent:'님도 해피하세요~'},
        {writer:'최철수',content:'좋은 시간 되세요'}
      ]}
)

db.article.find()

/*
3. 비밀게시판을 생성한다.
4. 비밀게시판에 작성자가 'noname'값을 가지는 글을 하나 작성한다.
5. 모든 글에 추천수 필드(upvote)를 추가하고 값을 0으로 설정한다
*/
secretboard_id=db.board.insertOne({name:'비밀게시판'}).insertedId
secretboard_id

db.article.insertOne({bid:secretboard_id,title:'1급 비밀입니다!!', content:'Top Secret',writer:'noname'})
//비밀게시판만 가져오기
db.article.find({bid:secretboard_id})

//자유게시판만 가져오기
db.article.find({bid:freeboard_id})
//5.
db.article.updateMany({},{$set:{upvote:0}})
db.article.find()
/*
6. 비밀게시판 글에 추천수를 1 증가시킨다 ==> {$inc:{필드명:1}}
7. 이미 댓글이 달린 자유게시판 글에 upvote 필드 없이 댓글을 추가한다.
8. 이미 댓글이 달린 글에 방금 달은 댓글에(특징을 기억해서 수정하자) 
    upvote 필드 값을 0으로 추가한다
==>배열요소값 수정 arraysFilters 파라미터 사용해보기.
*/
secretboard_id
//6. 비밀게시판 글에 추천수를 1 증가시킨다 ==> {$inc:{필드명:1}}
db.article.updateMany({bid:secretboard_id},{$inc:{upvote:1}})

db.article.find({bid:secretboard_id})
db.article.find()

//7. 이미 댓글이 달린 자유게시판 글에 upvote 필드 없이 댓글을 추가한다.
freeboard_id=db.board.find({name:'자유게시판'}).toArray()[0]._id
freeboard_id
db.article.updateOne({comment:{$size:2}},{$push:{comment:{writer:'김추가',content:'감기 조심 하세요'}}})

db.article.find({})
db.article.find({writer:'박해피'})
//8. 이미 댓글이 달린 글에 방금 달은 댓글에(특징을 기억해서 수정하자) 
//    upvote 필드 값을 0으로 추가한다
find_id=db.article.find({bid:freeboard_id,writer:'박해피'}).toArray()[0]._id
find_id
db.article.updateOne({_id:find_id},{$set:{'comment.$[myele].upvote':0}},
 {arrayFilters:[{'myele.writer':'김추가'}]})
db.article.find()
//----------------------------------------------------------------
db.article.deleteMany()
db.article.drop()
db.boardDB.drop()
db.dropDatabase()
//----------------------------------------------------------------
/*
# 도큐먼트를 집계하는 방법은 3가지가 있다
[1] db의 모든 정보를 가져와 애플리케이션 단계에서 집계하는 방법
[2] 몽고디비의 맵리듀스 기능을 이용하는 방법
[3] 몽고디비의 집계 파이프라인 기능을 이용하는 방법
- 이 중에 파이프라인기능을 이용하는 방법이 처리 속도도 빠르고 램메모리 소요도 적게쓴다. 
   다만 자유도는 나쁜 편(주어진 연산자로만 가져오는데 때로 원하는 결과를 얻지 못할 수 있음)
- 집계 명령은 수많은 데이터를 처리해서 작은 양의 정보를 애플리케이션에 전달하는 특징이 있다.
  정보를 최대한 작게 만든후 앱으로 작아진 정보를 전송하는 것이 더 효율적임
- 많은양의 정보를 몽고디비 내부에서 처리한다면 많은 양의 램메모리가 필요하지 않게된다.
- 집계 파이프라인 명령어는 도큐먼트를 순차적으로 받아서 집계 처리를 몽고디비 내부에서 한다.
  맵리듀스 방식은 자바스크립트 엔진과 정보교환을 위해 램을 사용하는데 이때 대량의 메모리가 필요하게 된다.
  집계 파이프라인을 사용하는 것이 가장 합리적으로 보이지만,
  하지만 상황에 따라 맵리듀스로 처리해야 한다던지 애플리케이션에서 집계처리해야 할때도 있다.
*/
//#  집계 파이프라인 명령어
/*
$project : select절
$match: where절
$group: group by 절  => $group을 사용하기 위해서는 _id값에 그룹화의 기준이 되는 값을 지정해야 한다.
$sort: order by 절
$limit
$unwind
*/
db
use mydb

db.articles.insertMany([
    { "author" : "john", "score" : 80, "views" : 100 },
    { "author" : "john", "score" : 85, "views" : 521 },
    { "author" : "ahn", "score" : 60, "views" : 1000 },
    { "author" : "li", "score" : 55, "views" : 5000 },
    { "author" : "annT", "score" : 60, "views" : 50 },
    { "author" : "li", "score" : 94, "views" : 999 },
    { "author" : "ty", "score" : 95, "views" : 1000 }
])
db.articles.find()
//select author, score from articles
// {$project:{필드명1:1, 필드명2:1,_id:0}}
db.articles.aggregate([{$project:{_id:0,author:1,score:1}}])

//$match : 조건을 걸어서 가져올때
//select * from articles where score>80
db.articles.aggregate([{$match:{score:{$gt:80}}}])

//select * from articles where author='li' and score >=60
db.articles.aggregate([{$match:{author:'li',score:{$gte:60}}}])

//select author, sum(score) as total from articles group by author
db.articles.aggregate([{
    $group:{_id:'$author',total:{$sum:'$score'}}
}])
db.articles.find()

//select author, sum(score) as total from articles group by author having sum(score)>100
db.articles.aggregate([{group},{조건match}])
db.articles.aggregate([{$group:{_id:'$author', total:{$sum:'$score'}}},{$match:{total:{$gt:100}}}])
//$sum
//$avg
//$min
//$max


use mydb
show collections
db.posts.find()

db.posts.insertMany([{author: '홍길동', title:'테스트1', wdate:'2022-12-12'}, 
{author: '홍길동', title:'테스트1', wdate:'2022-12-12'},
{author: '홍길동', title:'테스트1', wdate:'2022-12-12'},
{author: '홍길동', title:'테스트1', wdate:'2022-12-12'}])

 

해당 스터디는 아래 깃을 통해 업데이트 되고 있습니다.

https://github.com/yzpocket/Sparta99training

 

GitHub - yzpocket/Sparta99training

Contribute to yzpocket/Sparta99training development by creating an account on GitHub.

github.com