1. 도큐먼트
- 몽고DB의 핵심은 정렬된 키와 연결된 값의 집합으로 이루어진 도큐먼트
- 도큐먼트 표현 방식은 프로그래밍 언어마다 상이하지만 대부분의 언어는 Map, Hash, Dictionary와 같이 도큐먼트를 자연스럽게 표현하는 자료구조를 가짐
- i.g. 자바스크립트에서 도큐먼트는 객체로 표현
- 도큐먼트의 키는 문자열이며 다음 예외 몇 가지를 제외하면 어떤 UTF-8 문자든 사용 가능
- 키는 \0 (null 문자)을 포함하지 않음, \0은 키의 끝은 나타나는 데 사용
- .과 $ 문자는 몇 가지 특별한 속성을 가지며 특정 상황에만 사용해야 함, 해당 문자들은 보통 예약어로 취급해야 하며 부적절하게 사용하면 드라이버에서 경고 발생
- 도큐먼트의 값은 데이터형 또는 내장 도큐먼트 전체가 되기도 함
- 아래 예제에서 "greeting"의 값은 문자열이며, "views"의 값은 정수
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"greeting": "hello, world!", | |
"views": 3 | |
} |
- 몽고DB는 데이터형과 대소문자를 구별함
- 또한, 몽고DB에서는 키가 중복될 수 없음
2. 컬렉션
- 컬렉션은 도큐먼트의 모음
- 몽고DB의 도큐먼트가 관계형 데이터베이스의 행에 대응된다면 컬렉션은 테이블에 대응된다고 볼 수 있음
2.1 동적 스키마
- 컬렉션은 동적 스키마를 가짐
- 하나의 컬렉션 내 도큐먼트들이 모두 다른 구조를 가질 수 있다는 의미
- 도큐먼트들의 키, 키의 개수, 데이터형의 값은 모두 다름
- 다른 구조의 도큐먼트라도 같은 컬렉션에 저장할 수 있는데 `왜 별도의 컬렉션이 필요하지?`라고 생각할 수 있으나 몇 가지 합당한 이유가 있음
- 예를 들어 블로그 게시물 데이터 중 작성자 정보만 제거하는 요청이 들어왔을 때 동일한 컬렉션 내에서 조회된 데이터 구조가 상이할 경우 개발자나 관리자에게 어려움을 초래할 수 있음
- 컬렉션별로 목록을 뽑으면 한 컬렉션 내 특정 데이터형 별로 쿼리 해서 목록을 뽑을 때보다 훨씬 성능이 좋음
- 같은 종류의 데이터를 하나의 컬렉션에 모아두면 데이터 지역성 (Data Locality)에도 좋음, 블로그 게시물 여러 개를 조회하는 경우, 게시물과 저자 정보가 섞인 컬렉션보다 게시물만 들어 있는 컬렉션에서 뽑을 때 디스크 탐색 시간이 더 짧음
- 인덱스를 생성하려면 도큐먼트는 특정 구조를 가져야 하며 이러한 인덱스는 컬렉션별로 정의함, 같은 유형의 도큐먼트를 하나의 컬렉션에 넣음으로써 컬렉션을 효율적으로 인덱싱할 수 있음
- 스키마를 생성하고 관련된 유형의 도큐먼트를 그룹화하는 데는 타당한 이유가 있음
- 애플리케이션 스키마는 기본적으로 필요하지는 않지만 정의하면 좋음
- 몽고DB의 도큐먼트 유효성 검사 기능 (Document Validation Functionality)과 객체-도큐먼트 매핑 라이브러리 (Object-Document Mapping Library)를 이용하며, 이는 많은 프로그래밍 언어에서 사용 가능
2.2 네이밍
- 컬렉션은 이름으로 식별됨
- 컬렉션명은 어떤 UTF-8 문자열이든 사용 가능하지만 몇 가지 제약 조건이 있음
- 빈 문자열("")은 유효한 컬렉션명이 아님
- \0 (null 문자)은 컬렉션명의 끝을 나타내는 문자이므로 컬렉션명으로 사용 불가능
- `system.`으로 시작하는 컬렉션명은 시스템 컬렉션에서 사용하는 예약어이므로 사용할 수 없음
- 사용자가 만든 컬렉션은 이름에 예약어인 $를 포함할 수 없음
- 시스템에서 생성한 몇몇 컬렉션에서 $ 문자를 사용하므로 데이터베이스에서 사용하는 다양한 드라이버가 $ 문자를 포함하기는 하지만
- 이런 컬렉션에 접근할 때가 아니라면 $를 컬렉션명에 사용해서는 안됨
서브 컬렉션
- 서브 컬렉션의 네임스페이스에 . (마침표) 문자를 사용해 컬렉션을 체계화함
- i.g. 블로그 기능이 있는 애플리케이션은 blog.posts와 blog.authors라는 컬렉션을 가질 수 있음
- 이는 단지 체계화를 위함이며 blog 컬렉션이나 자식 컬렉션과는 아무런 관계가 없음
- 서브 컬렉션은 특별한 속성은 없지만 여러 몽고DB 틀에서 지원하므로 유용함
- 큰 파일을 저장하는 프로토콜인 GridFS는 콘텐츠 데이터와 별도로 메타데이터를 저장하는 데 서브 컬렉션을 사용
- 대부분의 드라이버는 특정 컬렉션의 서브 컬렉션에 접근하는 몇 가지 편리한 문법을 제공 i.g. 데이터베이스 셀에서 db.blog는 blog 컬렉션을, db.blog.posts는 blog.posts 컬렉션을 보여줌
3. 데이터베이스
- 몽고DB의 단일 인스턴스는 여러 데이터베이스를 호스팅할 수 있으며, 각 데이터베이스를 완전히 독리적으로 취급할 수 있음
- 한 애플리케이션의 데이터를 동일한 데이터베이스에 저장하는 것을 권장
- 데이터베이스를 나누면 하나의 몽고DB 서버에서 여러 애플리케이션이나 여러 사용자 데이터를 저장할 때 유용
- 데이터베이스는 컬렉션과 마찬가지로 이름으로 식별되며 어떤 UTF-8 문자열이든 사용할 수 있지만 몇 가지 제약 조건이 있음
- 빈 문자열("")은 유효한 데이터베이스 이름이 아님
- 데이터베이스 이름은 `/, \, ., ' ', *, <, >, :, |, ?, $, (단일 공간), \0 (null 문자)`를 포함할 수 없음
- 데이터베이스 이름은 대소문자를 구별
- 데이터베이스 이름은 최대 64 바이트
- 직접 접근은 가능하지만 다음과 같이 특별한 의미론 (semantics)을 갖는 예약된 데이터베이스 이름도 있음
- admin: admin 데이터베이스는 인증과 권한 부여 역할을 하며 일부 관리 작업을 하려면 해당 데이터베이스에 대한 접근이 필요함
- local: local 데이터베이스는 단일 서버에 대한 데이터를 저장하며 replica set에서 local은 복제 프로세스에 사용된 데이터를 저장함, 하지만 local 데이터베이스 자체는 복제되지 않음
- config: 샤딩된 몽고DB 클러스터는 config 데이터베이스를 사용해 각 샤드의 정보를 저장
- 컬렉션을 저장하는 데이터베이스의 이름을 컬렉션명 앞에 붙이면 올바른 컬렉션명인 네임스페이스를 얻음
- i.g. cms 데이터베이스의 blog.posts 컬렉션을 사용한다면 컬렉션의 네임스페이스는 cms.blog.posts가 됨
- 네임스페이스의 최대 길이는 120 바이트지만 실제로는 100 바이트보다 짧아야 함
4. 몽고DB 시작
- 서버를 시작하려면 원하는 유닉스 명령행 환경에서 mongod 실행 파일을 실행하거나 윈도우 환경에서 mongod.exe를 실행

- mongod는 argument 없이 실행하면 기본 데이터 디렉토리로 /data/db를 사용
- 데이터 디렉토리가 존재하지 않거나 쓰기 권한이 없을 때는 서버가 시작되지 않음
- 몽고DB를 시작하기 전에 데이터 디렉토리를 생성하고 해당 디렉토리에 쓰기 권한이 있는지 확인 필요
- 시작할 때 서버는 버전과 시스템 정보를 출력한 후 클라이언트의 연결을 기다리며 몽고DB는 기본적으로 27017번 포트에서 소켓 연결을 기다림
- 포트가 사용할 수 없는 상태일 때는 서버가 시작되지 않는데, 이러한 문제는 보통 다른 몽고DB 인스턴스가 시행 중이기 때문에 발생함
- mongod 서버를 실행한 셸에서 `ctrl + c`를 누르면 mongod가 안전하게 중지됨
5. 몽고DB 셸 소개
- 몽고DB는 명령행에서 몽고DB 인스턴스와 상호작용하는 자바스크립트 셸을 제공
- 셸은 관리 기능이나, 실행 중인 인스턴스를 점검하거나 간단한 기능을 시험하는 데 매우 유용
5.1 셸 실행
- mongo를 실행해 셸을 시작하면 자동으로 로컬 장비에서 실행 중인 몽고DB 서버에 접속을 시도함

- 셸은 완전한 자바스크립트 해석기이며 임의의 자바스크립트 프로그램을 실행함
- 기본적인 연산과 표준 자바스크립트 라이브러리의 모든 기능을 활용 가능
- 자바스크립트 함수를 정의하고 호출 가능
- 여러 줄의 명령도 작성 가능
- 엔터 키를 누르면 셸은 자바스크립트 구문이 완료됐는지 감지하며 구문이 완료되지 않았으면 다음 줄에서 계속 명령어를 입력 가능
- 엔터 키를 3회 연속 누르면 명령을 취소하고 > 프롬프트를 반환함
5.2 몽고DB 클라이언트
- 셸의 진수는 독자적으로 쓸 수 있는 몽고DB 클라이언트
- 셸은 시작할 때 몽고DB 서버의 mongo 데이터베이스에 연결하고, 데이터베이스 연결을 전역 변수 db에 할당
- 셸에서는 주로 해당 변수를 통해 몽고DB에 접근
- 셸은 자바스크립트 구문으로는 유효하지 않지만 SQL 셸 사용자에게 친숙한 추가 기능을 포함 i.g. 데이터베이스 선택
- db 변수에서 컬렉션도 접근 가능

3. 셸 기본 작업
- 셸에서 CRUD를 지원함
생성 (Create)
- insertOne 함수는 컬렉션에 도큐먼트를 추가
- i.g. 영화를 저장한다고 가정
- 도큐먼트를 나타내는 자바스크립트 객체인 movie라는 지역 변수를 생성하며 movie 변수는 "title", "director", "year"와 같은 키를 가짐
- 해당 객체는 유효한 몽고DB 도큐먼트이며 insertOne 함수를 이용해 movie 컬렉션에 저장 가능

- "_id" 키가 추가됐고 다른 key-value 쌍들은 입력한 대로 저장됐음
읽기 (Read)
- find와 findOne은 컬렉션을 쿼리 하는 데 사용
- 컬렉션에서 단일 도큐먼트를 읽으려면 findOne을 사용
- find와 findOne은 쿼리 도큐먼트 형태로 조건 전달도 가능하기 때문에 쿼리에서 일치하는 도큐먼트로 결과를 제한
- 셸은 find와 일치하는 도큐먼트를 20개까지 자동으로 출력하지만 그 이상도 조회할 수 있음

갱신 (Update)
- 게시물을 갱신하려면 updateOne을 사용하며 매개변수는 최소 두 개
- 첫 번째 매개변수는 수정할 도큐먼트를 찾는 기준
- 두 번째 매개변수는 갱신 작업을 설명하는 도큐먼트
- 갱신하려면 갱신 연산자인 set을 이용

삭제 (Delete)
- deleteOne과 deleteMany는 도큐먼트를 데이터베이스에서 영구적으로 삭제시킴
- 두 함수 모두 필터 도큐먼트로 삭제 조건을 지정
- 필터와 일치하는 모든 도큐먼트를 삭제하려면 deleteMany를 사용

6. 데이터형
- 몽고DB는 도큐먼트의 값으로 다양한 데이터형을 지원
6.1 기본 데이터형
- 몽고DB에서 도큐먼트는 자바스크립트 객체와 개념적으로 닮았다는 점에서 `JSON과 닮았다`라고 생각할 수 있지만 도큐먼트가 JSON보다 표현력 측면에서 우수함
- JSON은 데이터형을 null, Boolean, Number, String, Array, 그리고 Object만 지원하기 때문에 JSON의 표현력은 제한적
- JSON은 날짜형이 없어 날짜 다루기가 일반적인 경우보다 더 성가시며 숫자형이 있기는 하지만 한 가지뿐
- 부등소수점형과 정수형을 표현하는 방법이 없으며 32비트와 64비트도 구별하지 않음
- 함수나 정규 표현식과 같이 흔히 쓰이는 데이터형을 표현하는 방법도 없음
- 몽고DB는 JSON의 key-value 쌍 성질을 유지하면서 추가적인 데이터형을 지원하며 가장 일반적인 데이터형은 다음과 같음
- null: null 값과 존재하지 않는 필드를 표현하는 데 사용
- 불리언: 참과 거짓 값에 사용
- 숫자: 셸은 64비트 부동소수점 수를 기본으로 사용하기 때문에 3.14와 같은 소수도 저장 가능, 4 바이트 혹은 8 바이트의 부호 정수는 각각 NumberInt 혹은 NumberLong 클래스를 사용
- 문자열: 어떤 UTF-8 문자열이든 문자열형으로 표현 가능
- 날짜: 몽고DB는 1970년 1월 1일부터의 시간을 1/1000초 단위로 나타내는 64비트 정수로 날짜를 저장하지만 표준시가대는 저장하지 않음
- 정규 표현식: 쿼리는 자바스크립트의 정규 표현식 문법 사용 가능
- 배열: 값의 셋이나 리스트를 배열로 표현 가능
- 내장 도큐먼트: 도큐먼트는 부모 도큐먼트의 값으로 내장된 도큐먼트 전체를 포함 가능
- 객체 ID: 객체 ID는 도큐먼트용 12바이트 ID
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// null | |
{"x": null} | |
// 불리언 | |
{"x": true} | |
// 숫자 | |
{"x": 3.14} | |
{"x": 3} | |
{"x": NumberInt("3")} | |
{"x": NumberLong("3")} | |
// 문자열 | |
{"x": "foobar"} | |
// 날짜 | |
{"x": new Date()} | |
// 정규 표현식 | |
{"x": /foobar/i} | |
// 배열 | |
{"x": ["a", "b", "c"]} | |
// 내장 도큐먼트 | |
{"x": {"foo": "bar"}} |
- 다음은 상대적으로 덜 사용되는 데이터형 목록
- 이진 데이터: 임의의 바이트 문자열이며 셸에서는 조작 불가능, 이진 데이터는 데이터베이스에 UTF-8이 아닌 문자열을 저장하는 유일한 방법
- 코드: 쿼리와 도큐먼트는 임의의 자바스크립트 코드를 포함할 수 있음
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 코드 | |
{"x": function() {/* ... */}} |
6.2 날짜
- 자바스크립트에서 Date 클래스는 몽고DB의 날짜를 표현하는 데 사용
- 새로운 Date 객체를 생성할 때는 항상 Date()가 아닌 new Date()를 호출해야 함
- 함수로 new가 포함되지 않은 생성자를 호출하면 실제 Date 객체가 아닌 날짜의 문자열 표현을 반환
- 따라서 항상 Date 생성자를 사용하는 것을 권장
- new가 포함되지 않은 생성자와 혼용해서 사용할 경우 문자열과 날짜가 뒤범벅되고 문자열과 날짜는 서로 일치하지 않기 때문에 삭제, 수정, 쿼리 등 거의 모든 작업에서 문제를 일으킴
- 셸에서는 날짜가 현지 시간대 설정을 이용해 표시하지만 데이터베이스의 날짜는 1970년 1월 1일부터의 시간을 1/1000초 단위로 저장하며 표준 시간대 정보는 없음
6.3 배열
- 배열은 정렬 연산 (리스트, 스택, 큐)과 비정렬 연산 (Set)에 호환성 있게 사용 가능한 값
- 배열은 서로 다른 데이터형을 값을 포함
- 사실 배열값은 일반적인 key-value 쌍을 지원하는 어떤 데이터형 값이든 될 수 있으며 심지어 중첩 배열도 될 수 있음
{"things": ["pie", 3.14]}
- 도큐먼트 내 배열의 장점으로 몽고DB가 배열의 구조를 `이해한다`는 점과, 배열의 내용에 작업을 수행하기 우해 내부에 도달하는 방법을 안다는 점
- 따라서 배열에 쿼리 하거나 배열의 내용을 이용해 인덱스 생성 가능
- i.g. 위 예시에서 몽고DB는 3.14가 "things" 배열의 요소인 모든 도큐먼트를 쿼리 가능, 자주 쓰는 쿼리라면 "things" 키에 인덱스를 생성해 쿼리 속도를 향상할 수 있음
6.4 내장 도큐먼트
- 도큐먼트는 키에 대한 값이 될 수 있는데 이를 내장 도큐먼트라고 지칭
- 내장 도큐먼트를 사용해 데이터를 key-value 쌍의 평면적인 구조보다는 보다 자연스러운 방법으로 구성 가능
- 아래 예제에서 "address" 키에 대한 값은 "street", "city", "state"의 key-value 쌍을 갖는 내장 도큐먼트
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 한 사람의 정보를 나타내는 도큐먼트에 주소를 저장하기 위해 "address" 내장 도큐먼트로 중첩 | |
{ | |
"name": "John Doe", | |
"address": { | |
"street": "123 Park Street", | |
"city": "anytown", | |
"state": "NY" | |
} | |
} |
- 배열과 마찬가지로 몽고DB는 내장 도큐먼트의 구조를 이해하고, 인덱스를 구성하고, 쿼리 하며, 갱신하기 위해 내장 도큐먼트 내부에 접근함
- 관계형 데이터베이스를 사용한다면 정규화를 진행하여 위 예제를 두 개의 테이블에 분리된 두 개의 행으로 모델링했겠지만 몽고DB에서는 "people" 도큐먼트 내에 바로 "addresses" 도큐먼트를 내장 가능
- 내장 도큐먼트를 적절히 사용할 경우 좀 더 자연스럽게 정보를 표현 가능
- 하지만 몽고DB에서는 더 많은 데이터 반복 (Data Repetition)이 생길 수 있다는 단점이 있음
6.5 _id와 ObjectId
- 몽고DB에 저장된 모든 도큐먼트는 "_id" 키를 가지며 "_id" 키 값은 어떤 데이터형이어도 상관없지만 "ObjectId"가 기본
- 하나의 컬렉션에서 모든 도큐먼트는 고유한 "_id" 값을 가지며, 해당 값은 컬렉션 내 모든 도큐먼트가 고유하게 식별되게 함
- 두 개의 컬렉션이 있다면 각 컬렉션은 "_id" 값이 123인 도큐먼트를 가질 수 있지만
- 각 컬렉션은 "_id"가 123인 도큐먼트를 단 한 개만 가질 수 있음
ObjectIds
- ObjectId는 "_id"의 기본 데이터형
- ObjectId 클래스는 가벼우면서도, 여러 장비에 걸쳐 전역적으로 유일하게 생성하기 쉽게 설계됨
- 자동 증가하는 기본 키처럼 전통적인 것이 아닌 ObjectId를 사용하는 주요 이유는 몽고DB의 분산 특성 때문
- 여러 서버에 걸쳐 자동으로 증가하는 기본 키를 동기화하는 작업은 어려고 시간이 오래 걸림
- 몽고DB는 분산 데이터베이스로 설계됐기 때문에 샤딩된 환경에서 고유 식별자를 생성하는 것이 매우 중요함
- ObjectId는 12바이트 스토리지를 사용하며 24자리 16진수 문자열 표현이 가능
- ObjectId가 흔히 거대한 16진수 문자열로 표현되긴 하지만 바이트당 2자리를 사용하므로 실제로 문자열은 저장된 데이터의 두 배만큼 김
- 여러 개의 새로운 ObjectId를 연속으로 생성하면 매번 마지막 숫자 몇 개만 바뀌는데 이는 ObjectId가 생성되는 방식 때문
- ObjectId의 첫 4바이트는 1970년 1월 1일부터의 시간을 1/1000초 단위로 저장하는 타임스탬프
- ObjectId의 다음 5바이트는 랜덤 값
- 최종 3바이트는 서로 다른 시스템에서 충돌하는 ObjectId를 생성하지 않도록 랜덤 값으로 시작하는 카운터
- ObjectId의 앞 9바이트는 1초 동안 여러 장비와 프로세스에 걸쳐 유일성을 보장
- 마지막 3바이트는 단순히 증분 하는 숫자로, 1초 내 단일 프로세스의 유일성을 보장
_id 자동 생성
- 도큐먼트를 입력할 때 "_id" 키를 명시하지 않으면 입력된 도큐먼트에 키가 자동으로 추가됨
- 몽고DB 서버에서 관리할 수 잇지만일반적으로는 클라이언트 쪽 드라이버에서 관리함
7. 몽고DB 셸 사용
- 5절에서는 로컬 mongod 인스턴스에 연결했지만 사용자 시스템에서 연결할 수 있는 어떤 몽고DB 인스턴스든 셸을 연결 가능
- 다른 장비나 포트에 mongod를 연결하려면 셸을 시작할 때 호스트명, 포트, 데이터베이스를 명시해야 함
- i.g. mongo som-host:30000/myDB (이제 some-host:30000의 myDB 데이터베이스를 참조)
- mongo 셸을 시작할 때 mongod에 연결하지 않는 것이 편할 때도 종종 있음
- 셸을 --nodb 옵션을 주어 시작하면 어디에도 연결되지 않은 채 시작됨
- 시작한 후 원하는 시점에 new Mongo(호스트명)을 실행함으로써 mongod에 연결
7.1 셸 활용 팁
- mongo는 단순하게 자바스크립트 셸이므로 온라인 자바스크립트 문서를 참조하면 유용
- 또한 help를 입력하면 셸에 내장된 도움말을 볼 수 있음

- 데이터베이스 수준의 도움말은 db.help()로, 컬렉션 수준의 도움말은 db.foo.help()로 확인
- 함수의 기능을 알고 싶으면 함수명을 괄호 없이 입력하면 됨
- 그러면 함수의 자바스크립트 소스코드가 출력됨
- i.g. update 함수가 어떻게 작동하는지 궁금하거나 매개변수 순서가 기억나지 않을 때는 아래와 같이 입력

7.2 셸에서 스크립트 실행하기
- 다음과 같이 자바스크립트 파일을 셸로 전달해 실행할 수 있음
- 단순히 명령행에 스크립트만 넘기면 됨
- mongo 셸은 각 스크립트를 실행하고 빠져나옴
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ mongo script1.js script2.js script3.js | |
MongoDB shell version: 4.2.1 | |
connecting to: mongodb://127.0.0.1:27017 | |
MongoDB server version: 4.2.1 | |
loading file: script1.js | |
I am script1.js | |
loading file: script2.js | |
I am script2.js | |
loading file: script3.js | |
I am script3.js |
- 만약 셸 스크립트의 결과물을 다른 명령으로 전송하는 것을 고려한다면 결과물에서 "MongoDB shell version v4.2.0" 배너가 보이지 않도록 -quiet 옵션 사용
- 또한 load 함수를 사용해 대화형 셸에서 스크립트를 실행할 수 있음
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// -quiet | |
$ mongo server-1:30000/foo -quiet script1.js script2.js script3.js | |
// load | |
> load("script1.js") | |
I am script1.js | |
true | |
> |
- 스크립트는 다른 전역 변수와 마찬가지로 db 변수에 대한 접근 권한을 가짐
- 하지만 use db나 show collections와 같은 셸 보조자는 파일에서 작동하지 않음
- 셸 보조자와 대응하는 자바스크립트 용법은 다음과 같음
셸 보조자 | 같은 의미의 자바스크립트 |
use video | db.getSisterDB("video") |
show dbs | db.getMongo().getDBs() |
show collections | db.getCollectionNames() |
- 스크립트를 사용해 셸에 변수 입력도 가능
- i.g. 일반적으로 사용하는 helper function을 간단히 초기화하는 스크립트가 있을 수 있으며 해당 스크립트는 주어진 포트에서 로컬로 실행되는 데이터베이스에 연결하고 해당 연결에 db를 설정하는 connectTo 함수를 정의
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// defineConnectTo.js | |
// 데이터베이스에 연결하고 db 설정 | |
var connectTo = function(port, dbname) { | |
if (!port) { | |
port = 27017; | |
} | |
if (!dbname) { | |
dbname = "test"; | |
} | |
db = connect("localhost:" + port + "/" + dbname); | |
return db; | |
} | |
// 셸에 로드 | |
> load('defineConnectTo.js') | |
> typeof connectTo | |
function |
- 기본적으로 셸은 셸을 시작한 디렉토리에서 스크립트를 찾으며 스크립트가 현재 디렉토리에 없다면 셸에 상대 또는 절대 경로를 제공하면 됨
- i.g. ~/my-scripts 폴더 내 셸 스크립트를 넣었다면 load("/home/myUser/my-scripts/defineConnectTo.js")로 defineConnectTo.js를 로드할 수 있음
- 셸에서 명령행 프로그램을 실행시키기 위해 run 함수를 사용할 수 있지만 해당 방법은 출력이 이상한 형태로 나타나고 파이프를 지원하지 않기 때문에 제한적으로 사용됨
7.3 .mongorc.js 생성하기
- 자주 로드되는 스크립트를 .mongorc.js 파일에 넣을 수 있음
- i.g. 로그인할 때 사용자를 맞이하는 셸이 있다고 가정했을 때 홈 디렉토리 내 .mongorc.js 파일을 만들고 다음과 같이 추가하면 됨
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// .mongorc.js | |
var compliment = "attractive", "intelligent", "like Batman"]; | |
var index = Math.floor(Math.random() * 3); | |
print("Hello, you're looking particularly " + compliment[index] + " today!"); | |
// 셸 시작 | |
$ mongo | |
MongoDB shell version: 4.2.1 | |
connecting to: test | |
Hello, you're looking particularly intelligent today! | |
> |
- 해당 스크립트를 통해 사용하고 싶은 전역 변수를 설정하고, 긴 별칭을 짧게 만들고, 내장 함수를 재정의 할 수 있음
- .mongorc.js의 일반적인 용법 중 하나는 더 `위험한` 셸 보조자를 제거하는 것
- i.g. dropDatabase나 deleteIndexes 같은 함수가 아무것도 수행하지 않게 재정의할 수 있음
- 의도치 않게 키를 잘못 눌러 명령을 실행했을 때 도움을 줄 뿐이며 악의적인 사용자로부터 보호하는 기능은 아님
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var no = function() { | |
print("Not on my watch."); | |
} | |
// 데이터베이스 삭제 방지 | |
db.dropDatabase = DB.prototype.dropDatabase = no; | |
// 컬렉션 삭제 방지 | |
DBCollection.prototype.drop = no; | |
// 인덱스 삭제 방지 | |
DBCollection.prototype.dropIndex = no; | |
// 인덱스 삭제 방지 | |
DBCollection.prototype.dropIndexes = no; |
- 셸을 시작할 때 --norc 옵션을 통해 .mongorc.js의 로딩을 비활성화시킬 수 있음
7.4 프롬프트 커스터마이징하기
- 기본 셸 프롬프트는 문자열이나 함수에 prompt 변수를 설정해 재정의 가능
- i.g. 완료되는데 몇 분이 걸리는 쿼리를 실행할 때, 마지막 작업이 완료된 시각을 얻기 위해 현재 시각을 출력하는 프롬프트 생성
- i.g. 현재 사용하는 데이터베이스를 보여주는 프롬프트
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 현재 시각 출력 | |
prompt = function() { | |
return (new Date()) + "> "; | |
} | |
// 현재 사용하는 데이터베이스 | |
prompt = function() { | |
if (typeof db == 'undefined') { | |
return '(nodb)> '; | |
} | |
// 마지막 db 연산 확인 | |
try { | |
db.runCommand({getLastError:1}); | |
} catch (e) { | |
print(e); | |
} | |
return db+"> "; | |
} |
- 일반적으로 프롬프트 함수는 getLastError 호출을 포함해야 함
- 그러면 셸의 연결이 끊겼을 때 쓰기에서의 오류를 감지해서 자동으로 다시 연결해 줌 i.g. mongod 재시작할 때
- 항상 사용되는 사용자 정의 프롬프트나 셸 간에 전환할 수 있는 몇 가지 프롬프트를 구성할 때 mongorc.js 파일에 정의하는 것을 권장
7.5 복잡한 변수 수정하기
- 셸에서 mutiline 지원은 다소 제한적이며 이전 행들을 편집할 수 없음
- i.g. 15번째 줄에서 작업하던 도중에 첫 번째 줄에 오타가 있다는 것을 깨달았을 때 매우 번거로워짐
- 따라서 코드나 객체 블록이 클 경우 에디터를 통해 편집하는 것을 권장
- 셸에서 EDITOR 변수를 설정할 경우 `edit 변수명`과 같은 형식으로 변수를 에디터에서 편집 가능
- 변경을 완료한 뒤 저장하면 변수가 구문 분석되고 셸에 다시 로드됨
- EDITOR = "EDITOR 경로"를 .mongorc.js 파일에 추가하고 나면 더는 설정에 대해 걱정할 필요 없음
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
> EDITOR="/usr/bin/vscode" | |
> var wap = db.books.findOne({title: "War and Peace"}); | |
> edit wap |
7.6 불편한 컬렉션명
- 컬렉션명이 예약어가 아니거나 유효하지 않은 자바스크립트 속성명이 아니라면 db.collectionName 구문으로 컬렉션을 항상 가져올 수 있음
- i.g. version이라는 컬렉션에 접근한다고 가정했을 때 db.version은 db의 메서드이므로 db.version이라고 사용할 수 없음
- db.version을 실행하면 실행 중인 몽고DB 서버의 버전을 반환함
- 실제로 version 컬렉션에 접근하기 위해서는 getCollection 함수를 사용해야 함
- db.getCollection("version");
- 다른 방법으로, 배열 접근 구문을 사용해 유효하지 않은 속성명을 피할 수 있음
- 자바스크립트에서 x.y는 x['y']와 동일하며 이는 서브 컬렉션이 상수 이름뿐 아니라 변수를 이용해서도 접근할 수 있음을 의미
- 따라서 어떤 작업을 모든 blog 서브 컬렉션에 대해 수행해야 하는 경우 다음과 같은 코드를 사용해 반복함
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var collections = ["posts", "comments", "authors"]; | |
for (var i in collections) { | |
print(db.blog[collections[i]]); | |
} |
참고
몽고DB 완벽 가이드 3판 - 한빛미디어
반응형
'DB > 몽고DB 완벽 가이드 3판' 카테고리의 다른 글
[4장] 쿼리 (0) | 2025.03.29 |
---|---|
[3장] 도큐먼트 생성, 갱신, 삭제 (1) | 2025.03.28 |
[1장] 몽고DB 소개 (1) | 2025.03.26 |