(MongoDB 강의 내용 정리 - 1. 에 이어서 진행되는 내용)
[ 순서 ]
4. Delete
5. Session & Transaction
6. 검색
7. 맵 리듀스
* 내가 공부한 내용들은 정리한 글임
틀린 내용, 부족한 내용이 있을 수 있으니
(혹시라도 이 글을 볼 사람이 있을 지는 모르겠다만)
암튼 참고하고 유의하셈
4. D (삭제)
(1) * 예시로 바로 설명
> db.col3.deleteOne({a:10})
a필드 값이 10인 document를 삭제한다.
(document가 여러 개라면, 그 중 최우선으로 검색된 document를 삭제한다.)
> db.col3.deleteMany({a:10})
a필드 값이 10인 document 전체를 모두 삭제한다.
5. 세션 & 트랜잭션
(1)
Session ?
- 같은 사용자에게서 온 명령인지 아닌지 구분하기 위해 사용됨
> db.getMongo().startSession()
Session Id를 생성
> sessionId = db.getMongo().startSession()
"sessionId"라는 변수에 Session Id를 저장
> sessionId.endSession()
해당 Session Id에 대한 Session을 종료
* . endSession을 했더라도 "sessionId"라는 변수의 값은 여전히 존재한다 (단순히 Session이 종료되는 것임)
(2)
Transaction ?
- 목적
A의 계좌에서 B의 계좌로 100을 이체한다고 해보자.
그럼 2개의 명령문이 실행되어야 한다.
1) A계좌에서 -100
2) B계좌에서 +100
그런데 무슨 이유에서인지 1)은 실행이 되었는데, 2)는 실행이 되지 않았다면?
그러면 100은 그냥 사라져버린 것이 된다.
이런 상황을 막기 위해
여러 개의 명령들을 하나의 트랜잭션에 묶어서 실행시키는데,
이 경우에 만약 명령문들 중 하나라도 에러가 난다면
트랜잭션 내에서 실행되었던 모든 명령은 실행이 취소된다.
(이러한 속성을 원자성이라고 하는데, 다음에 기회될 때 자세히 알아보자)
- 세션이랑 무슨 상관?
여러 사람이 같은 명령문을 실행시켰을 때,
두 번째 실행시킨 명령문에서 에러가 났다해서 첫 번째로 실행이 완료된 명령문을 다시 취소시키면 안되니까.
(트랜잭션 => 안전성 , 세션 => 독립성 으로 보면 될 듯)
- 사용법
* 트랜잭션은 복제되었거나, 샤딩이 된 환경에서만 사용 가능
그 외의 환경에서는 에러가 나도 트랜잭션이 작동 안함
예시)
> sessionId = db.getMongo().startSession()
sessionId.startTransaction({readConcern:{level:'snapshot'}, writeConcern:{w:'majority'}})
db.col2.updateOne({name:"홍길동2"}, {$inc:{age:-10}})
db.col2.updateOne({name:"호세"}, {$inc:{age:10}})
sessionId.commitTransaction()
sessionId.endSession()
* startTransaction 안의 옵션들은 나중에 알아보자.
Replica Set, Arbiter 등등 추가적인 개념들이 더 있으나
이는 개발자보다는 서버 관리자에게 더 크게 요구되는 지식이다 - 난 개발자임
6. 검색 * 예시로 바로 설명
(1) 관계 연산자
> db.col2.find( { age: {$gte:21} } )
age필드의 값이 21이하인 document들을 조회
*
$gt : greater than
$gte : greater than, or equal
$lt : less than
$lte : less than, or equal
$ne : not equal
> db.col2.find({age:{$gte:21, $lte:50}})
age필드의 값이 21이상, 50이하 인 document들을 조회
> db.col2.find( { age: {$nin: [10, 21] } } )
(배열 활용) age필드의 값이 10 또는 21이 아닌 document들을 조회
* nin : not-in
(2) 정규표현식
> db.col2.find( { name: {$regex: '홍'} } )
name필드 값에 '홍'이 포함되는 document 조회
*
'^홍' : '홍'으로 시작되는 문자열
'홍$' : '홍'으로 끝나는 문자열
(3) 배열 값 검색
> db.col2.find( {'etc': {$elemMatch: {'likenum': {$in: [10, 22]} } } } )
etc필드의 배열값 likenum에, 요소로 10 또는 22를 가지고 있는 document를 조회
> db.col2.find( {'etc': {$elemMatch: {'likenum': {$nin: [10, 22]} } } } )
etc필드의 배열값 likenum에, 요소로 10 또는 22가 아닌 값을 가지고 있는 document를 조회
(배열 안에 10 또는 22가 있는 document를 걸러내는 옵션이 아니다.)
> db.col2.find( {'etc': {$elemMatch: {'likenum': {$all: [14, 22, 3, 4, 5]} } } } )
etc필드의 배열인 likenum 전체의 값이 [14, 22, 3, 4, 5]와 일치하는 document를 조회
> db.col2.find( {'etc': {$elemMatch: {'likenum': {$size: 5} } } } )
etc필드의 배열인 likenum의 길이가 5인 document를 조회
(4) 논리 연산자
> db.col2.find( {$and: [ {age:{$gt:10}}, {age:{$lt:50}} ] } )
10 < age < 50 인 document를 검색
> db.col2.find( {$or: [ {age:{$gt:10}}, {age:{$lt:50}} ] } )
age > 10 또는 age < 50 인 document
(5) 텍스트 연산자
- 텍스트 연산자 사용하려면 "인덱스" 필요
- 인덱스?
- 보다 빠르고 편리하게 검색 가능 (자주 검색하는 필드에 설정해주면 좋음)
- 숫자, 문자열만 허용, object는 인덱스로 설정 불가능
> db.col2.createIndex({name:"text"})
name필드에 인덱스 지정
> db.col2.createIndex( {name:"text" , address:"text"} )
name필드와 address필드를 인덱스로 설정
> db.col2.dropIndexes()
설정된 인덱스 삭제
(name필드가 인덱스로 설정되어 있을 때)
> db.col2.find({$text: {$search: '호세'}})
(name필드를 지정해주지 않았어도) name필드의 값이 '호세'인 document를 검색
> db.col2.find( {$text: {$search: 'mike', $caseSensitive:true} } )
$caseSensitive : 대소문자를 구별하여 검색
> db.col2.find({$text: {$search: "호세, 홍길동"}})
name필드의 값이 호세 또는 홍길동 인 document를 검색
> db.col2.find({$text: {$search: "\"호세, 홍길동\""}})
name필드의 값이 "호세, 홍길동"인 document 검색
(6) 배열 검색 심화
likenum 배열 안에 22가 있는 document를 검색
> db.col2.find({etc: {$elemMatch: {likenum: 22}}})
* 해당되는 document의 field 전체를 출력
> db.col2.find({}, {etc: {$elemMatch: {likenum: 22}}})
* 해당되는 document는 field 중에서 배열 field만 출력
해당되지 않는 document는 id만 출력
> db.col2.find({etc: {$elemMatch: {likenum: 22}}}, {"etc.$":true})
* 해당되는 document는 field 중에서 배열 field만 출력
해당되지 않는 document는 출력하지 않음
> db.col2.find({etc: {$elemMatch: {likenum: 22}}}, {"etc.likenum": {$slice: 1}})
* 해당되는 document의 field값 배열에서 첫 번째 요소만 출력함(인덱스 번호로 바꾸면 0번인 값)
> db.col2.find({etc: {$elemMatch: {likenum: 22}}}, {"etc.likenum": {$slice: [1,3]}})
* 해당되는 document의 field값 배열에서 1번째에서 3번째 요소(총 3개)를 출력함(이 때는 인덱스 번호를 기준으로 함)
7. 맵 리듀스
(생략)
이유 1) 버전 차이(나 7 , 강의 4.2) : .mapReduce()는 deprecated된 함수임
이유 2) 솔직히 뭔소리인지 못알아듣겠음
이유 3) 현재 내가 진행하는 프로젝트에서 크게 필요로 하는 개념은 아님
우선 여기까지 공부하고, 다시 프로젝트로 넘어가자
'개발 > 학습' 카테고리의 다른 글
MongoDB(Mongoose) - connect / createConnection (0) | 2024.08.25 |
---|---|
MongoDB - 데이터 타입 수정 ; 문자열을 날짜로 (0) | 2024.07.14 |
MongoDB 강의 내용 정리 - 1. (0) | 2024.04.10 |