MongoDB 설치/기본
- IoT
- 2022. 4. 4.
MongoDB 다운로드
MongoDB
- Document oriented 데이터베이스
[실행방법]
- mongodb 서버 실행 : mongod --dbpath 저장할폴더
- mongodb 클라이언트 실행 : mongo
[용어]
RDBMS와 비교
Database
- Collection을 담고 있는 컨테이너
Collection
- RDBMS의 테이블과 비슷한 개념(스키마가 없다. - 정해진 구조가 없다.)
Document
- RDBMS에서 레코드와 비슷한 개념
Embedded documnet
- 테이블 조인과 비슷한 개념
[기본 명렁어]
show dbs - 데이터베이스의 리스트를 확인
use sample - sample이라는 데이터베이스 생성
- 작업하고 싶은 데이터베이스 로그인
db - 현재 작업중인 데이터베이스를 확인
db.stats() - db의 현재 상태
show collections - 현재 collection을 보여줌
db.createCollection("emp"); - emp라는 collection을 만듬
db.emp.renameCollection("employee"); - emp collection을 employee로 바꿈
db.help() 입력하면 모든 명렁어를 볼 수 있다.
버전 : 3.6.23
다운로드를 해준다.
설치를 다 완료 해주면
내 PC -> 오른쪽 클릭 -> 속성
새로 만들기 하고 MongoDB 설치된 경로 bin파일 까지 경로를 추가 해주면 된다.
그리고 cmd에 들어가서
mongod --dbpath 파일저장경로 를 넣어주면
(서버 접속하는 방법)
이런식으로 뜰거다
또 cmd를 하나 더 띄어주고
mongo 입력해주면 이렇게 뜬다
(클라이언트 접속하는 방법)
mongo에 들어 온것이다
Document삽입 (데이터 insert)
- mongodb는 데이터를 json방식으로 관리
- 컬렉션이 존재하지 않아도 insert를 하면 자동으로 컬렉션이 만들어진다.
1) insert메소드
- db.컬렉션명.insert({필드명1:"필드값1",필드명2:"필드값2" ...})
2) 배열
- json의 배열과 동일하게 표현
{필드명1:["값1","값2","값3","값4", ...]}
Document조회
=> select * from 테이블명 과 동일
- 컬렉션에 저장된 document를 조회
- db.컬렉션명.find(조건, 조회할 필드에 대한 정보를 정의)
1) query(조건)
- 조회할 필드에 대한 정보를 json형식으로 표기
[qurey연산자 - 비교 연산자]
$eq : 주어진 조건의 값과 일치(==) - db.컬렉션명.find({필드명:{$eq:찾을값}})
$gt : 조건값보다 큰 값(greater than : >)
$gte : 조건값보다 크거나 같은 값(greater than or equal: >=)
$lt : 조건값보다 작은 값(less than : <)
$lte : 조건값보다 작거나 같은(less than or equal <=)
$ne : 조건값과 일치하지 않는(not equal)
$in : select문의 in연산자와 동일 - 조건 값이 여러 값(배열)과 비교해서 일치하는지 확인
- db.컬렉션명.find({필드명:{$in:[배열]}})
$nin : 배열의 명시한 값들과 비교해서 일치하지 않는 값을 확인 not in
java점수가 90이상 100이하인 document 조회하기
db.score.find({java:{$gte:90,$lte:100}})
[query연산자 - 논리연산자]
- 조건은 배열로 정의
$and : 두 개 이상의 조건이 모두 true -> true
db.컬렉션명.find({$and:[{필드명:"필드값"},{필드명:"필드값"}]})
$not : 조건을 만족하지 않는 document와 조건을 판단할 필드가 존재하지 않는 document를 모두 조회(단일조건)
db.컬렉션명.find({필드명:{$not:{$lte:"필드값"}}})
$nor : 정의한 모든 조건을 만족하지 않는 document를 조회
db.컬렉션명,find({$nor:[{필드명:"필드값"},{필드명:"필드값"}, ...]})
$or : 두 개 이상의 조건 중 하나라도 true -> true
db.컬렉션명.find({},{id:1,name:1,dept:1})
=>모든것을 검색하는데 id,name,dept 검색해라
[Null 비교]
db.컬렉션명.find({필드명:null}) - 필드가 없거나 값이 null인 document를 조회한다
db.컬렉션명.find({필드명:{$exists:false}}) - 필드가 존재하지 않는 경우만 조회
[Cursor 메소드]
var alldata = db.score.find()
var size = db.score.find().count()
while(alldata.hasNext()) { //hasNext() - 저장된 document의 갯수만큼 반복해서 작업
var one = alldata.next() //document하나 꺼내서 반환
one.num = 10000
db.score.save(one) // score컬렉션에 작업한 one에 저장된 document를 save
}
count() : cursor안에 포함된 document의 갯수를 반환
db.getCollection("컬렉션명").distinct("필드명") - 필드의 중복을 제거한 값을 배열로 리턴
db.getCollection("컬렉션명").distinct("필드명").length - 갯수를 반환
limit(숫자) : limit에 정의한 갯수만큼 document 조회
db.컬렉션명.find({},{id:1,name:1}).sort({필드명:오름차순 or 내림차순}).limit(5)
skip(숫자) : skip에 정의한 갯수만큼 document를 제외하고 출력
[정규표현식]
문자열에서 패턴과 일치하는 문자가 있는지 찾을 수 있도록 지원
-----
문자, 기호를 이용해서 특정 문자를 찾는다.
문자나 기호는 내부적으로 의미를 갖고 있다. 거의 대부분의 언어에서 동일하게 작업
"^(?=.*[A-Za-z])(?=.*[0-9])(?=.*[$@$!%*#?&])[A-Za-z[0-9]$@$!%*#?&]{8,20}$";
^ : 문자열의 시작
$ : 문자열의 종료
. : 임의의 한 글자 의미(한글, 영문 상관없음)
| : or의 의미
i : 대소문자 구분없이 조회
/값/ : RDBMS의 like연산과 동일 = where addr like %값%과 동일
A-Z : 영문자대문자
a-z : 영문자소문자
0-9 : 숫자
가-힇
Document 수정(update)
- CRUD를 위한 모든 메소드는 json 형식으로 정의해야 한다
[구문]
db.컬렉션명.update(<filter>,<update>,<options>)
<filter>
- 조건 (sql update문의 where절)
{조건필드 : 값...}
<update>
- set절 (변경할 필드와 값)
- 업데이트 연산자와 함께 명시
업데이트 연산자를 명시하지 않으면 조건에 만족하는 document(제일 먼저 찾는 document만)를 찾아서 저장되어 있는 모든 필드값을 지우고 명시되어 있는 컬럼으로 교체
- 업데이트 연산자
$set : 해당 필드의 값을 변경
$inc : 지정한 값 만큼 필드의 값을 증가
- 업데이트할 필드가 존재하지 않으면 새로 추가한다.
db.emp.update({id:"kim"},{pass:"123456789"})
<filter> <update>
db.emp.update({id:"kim"},{$set:{업데이트할 컬럼의 정보...}})
db.emp.update({id:"kim"},{$set:{pass:"123456789"}})
db.컬렉션명.update({조건필드:조건값}, {$inc:{업데이트할 필드:값}})
필드의 값이 추가된 값만큼 증가
db.emp.update({id:"kim"},{$inc:{val1:3000}},{multi:true})
배열 데이터를 수정
- $push : 배열에 요소를 추가 (중복 허용)
db.score.update({id:"jang"},{$push:{"favorites.city":"천안"}})
db.score.update({id:"jang"),($push:{"favorites.city":["천안","가평","수원"]}}) 이렇게하면 배열이 들어가게됨
db.score.update({id:"jang"},{$push:{"favorites:city":{$each:["천안","가평","수원"]}}}) 해결방법
$each는 push나 addToset에서만 사용할 수 있다.
db.score.update({id:"jang"},{$push:{"favorites:city":{$each:["천안","가평","수원"],$sort:1}}}) 오름차순으로 정렬됨
$sort:-1 = 내림차순으로 정렬됨
- $addToSet : 배열에 요소를 추가 (중복 불가)
db.score.update({id:"jang"},{$addToSet:{"favorites.city":"천안"}})
- $pop : 첫번째 or 마지막요소 제거
db.score.update({id:"jang"},{$pop:{"favorites.city":1}}) 마지막요소 제거
db.score.update({id:"jang"},{$pop:{"favorites.city":-1}}) 첫번째요소 제거
- $pull : 배열의 요소들 중 원하는 아이템을 제거
db.score.update({id:"jang"},{$pull:{"favorites.city":"천안"}})
- $pullAll : 배열의 요소 조건을 모두 제거
db.score.update({id:"jang"},{$pullAll:{"favorites.city":["천안","가평"]}})
<options>
- 업데이트할 때 기본으로 설정된 기능을 변경하고 싶은 경우 사용
- mulit : true
mulit옵션을 true로 설정하면 조건에 만족하는 모든 document를 찾아서 필드를 변경한다.
db.emp.update({id:"kim"},{$set:{pass:"123456789"}},{multi:true})
filter update options
문제)
db.score.insert({id:"hong",name:"홍길동",dept:"인사",addr:"서울",java:100,servlet:88})
db.score.insert({id:"kim",name:"김민선",dept:"전산",addr:"인천",java:99,servlet:98})
db.score.insert({id:"lee",name:"이문세",dept:"인사",addr:"인천",java:88,servlet:77})
db.score.insert({id:"test",name:"테스트",dept:"총무",addr:"대구",java:97,servlet:80})
db.score.insert({id:"park",name:"박수홍",dept:"인사",addr:"대구",java:56,servlet:98})
db.score.insert({id:"jang",name:"장동건",dept:"총무",addr:"제주",java:77,servlet:100})
db.score.insert({id:"kang",name:"강감찬",dept:"전산",addr:"제주",java:88,servlet:92})
db.score.insert({id:"kkang",name:"강동원",dept:"전산",addr:"서울",java:98,servlet:82})
db.score.insert({id:"jjang",name:"장길산",dept:"인사",addr:"인천",java:30,servlet:88})
db.score.insert({id:"song",name:"송미미",dept:"전산",addr:"서울",java:90,servlet:55})
db.score.insert({id:"na",name:"나나나",dept:"인사",addr:"인천",java:100,servlet:100})
이것을 추가하고
1. addr이 서울인 사람의 mgr:"jang"을 추가 하시오
2. id가 kang인 사람의 dept를 "총무"로 변경
3. dept가 "전산"인 모든 사람들의 addr을 "안양"으로 수정
4. id가 jang인 document의 bonus를 1000추가하기
5. dept가 총무인 모든 document에 bonus를 2000추가하기
답 : 1. db.score.update({addr:"서울"},{$set:{mgr:"jang"}},{multi:ture})
2. db.score.update({id:"kang"},{$set:{dept:"총무"}},{multi:true})
3. db.score.update({dept:"전산"},{$set:{addr:"안양"}},{multi:true})
4. db.score.update({id:"jang"},{$inc:{bonus:1000}},{multi:true})
5. db.score.update({dept:"총무"},{$inc:{bonus:2000}},{multi:true})
Document 삭제
- drop()
db.컬렉션명.drop() - 컬렉션 삭제
- remove({필드명:"필드값"})
db.컬렉션명.remove({필드명:"필드값"})
문제
1. exam collection에서 이름과 주소와 servlet점수를 출력해보자
db.exam.find({},{id:1,addr:1,servlet:1})
2. exam collection에서 java점수 중 70점 이상을 출력해보자
db.exam.find({java:{$gte:70}})
3. exam collection에서 이름, java점수를 출력하고 bonus가 2000이상
인 사람만 출력해보자
db.exam.find({bonus:{$gte:2000}},{name:1,java:1})
4. exam에서 dept가 인사이면서 addr이 안양이거나 대구인 document 출력
db.exam.find({$and:[{dept:"인사"},{$or:[{addr:"안양"},{addr:"대구"}]}]})
5. exam이 70에서 90사이이며 dept가 총무인 document 조회
db.exam.find({$and:[{servlet:{$gte:70, $lte:90}},{dept:"총무"}]})
6. exam에서 이름에 김씨인 사람 조회해보기
db.exam.find({name:/^김/})
7. exam에서 servlet점수가 가장 낮은 document와 가장 높은 document 출력
db.exam.find().sort({servlet:-1}).limit(1)
db.exam.find().sort({servlet:1}).limit(1)
8. java점수가 가장 높은 document중에 7개를 출력하되 2개를 건너뛰고 출력
db.exam.find().sort({java:-1}).limit(7).skip(2)
9. 아이디에 n과 o가 들어가는 document 구하기
db.exam.find({id:/n|o/})