다른 몽고DB 인스턴스에 연결
어떤 몽고DB 인스턴스든 셸을 연결할 수 있다. 다른 장비나 포트에 mongod를 연결하려면 셸을 시작할 때 호스트명, 포트, 데이터베이스를 명시해야 한다.
몽고DB 컨테이너를 하나 더 띄우고 다른 한쪽에서 접속을 해보자.
접속을 위해서는 IP를 확인해야 하므로 컨테이너의 IP를 알아내야 한다.
$ docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' mongodb2
172.17.0.3
mongodb2 컨테이너의 IP는 172.17.0.3이다.
이제 다시 mongodb 컨테이너로 접속해 mongodb2 컨테이너 안에 몽고DB에 접속해보자.
접속할때는 mongo {IP}:{PORT}/{DATABASE} 명령어로 접속한다.
$ docker exec -it mongodb bash
$ mongo 172.17.0.3:27017/test
MongoDB shell version v5.0.8
connecting to: mongodb://172.17.0.3:27017/test?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("d07a97f0-3791-4fa3-90f0-4602c569d4f3") }
MongoDB server version: 5.0.8
>
db는 이제 mongodb2 컨테이너 안 몽고DB의 test 데이터베이스를 참조한다.
mongo 셸을 시작할 때 mongod에 연결하지 않는 것이 편할 떄도 종종 있다.
셸을 --nodb 옵션을 주어 시작하면 어디에도 연결되지 않은 채 시작된다.
$ mongo --nodb
MongoDB shell version: 5.0.8
> db
uncaught exception: ReferenceError: db is not defined :
시작한 후 원하는 때에 new Mongo(호스트명)를 실행함으로써 mongod에 연결한다.
> conn = new Mongo("172.17.0.3:27017")
connection to 172.17.0.3:27017
> db = conn.getDB("logs")
logs
이 두 명령어를 실행하면 기본적으로 db를 사용할 수 있으며, 다른 데이터베이스나 서버에 언제든지 연결할 수 있다.
셸 활용 팁
mongo는 단순하게 보면 자바스크립트 셸이므로 help를 입력하면 셸에 내장된 도움말을 볼 수 있다.
> help
db.help() help on db methods
db.mycoll.help() help on collection methods
sh.help() sharding helpers
rs.help() replica set helpers
help admin administrative help
help connect connecting to a db help
help keys key shortcuts
help misc misc things to know
help mr mapreduce
show dbs show database names
show collections show collections in current database
show users show users in current database
show profile show most recent system.profile entries with time >= 1ms
show logs show the accessible logger names
show log [name] prints out the last segment of log in memory, 'global' is default
use <db_name> set current database
db.mycoll.find() list objects in collection mycoll
db.mycoll.find( { a : 1 } ) list objects in mycoll where a == 1
it result of the last line evaluated; use to further iterate
DBQuery.shellBatchSize = x set default number of items to display on shell
exit quit the mongo shell
데이터베이스 수준의 도움말은 db.help()로, 컬렉션 수준의 도움말은 db.foo.help()로 확인한다.
함수의 기능을 알고 싶으면 함수명을 괄호없이 입력하면 함수의 코드가 출력된다.
> db.test.updateOne
function(filter, update, options) {
var opts = Object.extend({}, options || {});
// Pipeline updates are always permitted. Otherwise, we validate the update object.
if (!Array.isArray(update)) {
// Check if first key in update statement contains a $
var keys = Object.keys(update);
if (keys.length == 0) {
throw new Error(
"the update operation document must contain at least one atomic operator");
}
// Check if first key does not have the $
if (keys[0][0] != "$") {
throw new Error('the update operation document must contain atomic operators');
}
}
...
셸에서 스크립트 실행하기
셸을 대화형으로 사용하는 방법 외에 다음과 같이 자바스크립트 파일을 셸로 전달해 실행할 수도 있다.
단순히 명령행에 스크립트만 넘기면 된다.
$ vim MyScript1.js
print("This is MyScript1")
$ vim MyScript2.js
print("This is MyScript2")
$ mongo MyScript1.js MyScript2.js
MongoDB shell version v5.0.8
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("5b1956d5-5708-4d17-bd4a-d723389d4ee1") }
MongoDB server version: 5.0.8
loading file: MyScript1.js
This is MyScript1
loading file: MyScript2.js
This is MyScript2
셸은 각 스크립트를 실행하고 빠져나온다.
다른 몽고DB 인스턴스에 접근해 스크립트를 실행할수도 있다.
만약 셸 스트립트의 결과물을 다른 명령으로 전송하는 것을 고려한다면 "MongoDb shell version v5.0.8" 배너가 보이지 않도록 --quiet 옵션을 사용한다.
$ mongo 172.17.0.3:27017/logs --quiet MyScript1.js MyScript2.js
loading file: MyScript1.js
This is MyScript1
loading file: MyScript2.js
This is MyScript2
이는 셸을 명령어 파이프라인의 일부로 사용할 수 있음을 보여준다.
또한 load 함수를 사용해 대화형 셸에서 스크립트를 실행할수도 있다.
> load("MyScript1.js")
This is MyScript1
true
스크립트 db 변수에 대한 접근 권한을 가진다.
하지만 use나 show, show collection와 같은 셸 보조자는 파일에서 작동하지 않는다.
이들은 대응되는 유효한 자바스크립트 용법으로 사용해야 한다.
셸 보조자 | 자바스크립트 용법 |
use {dbName} | db.getSisterDB("{dbName}") |
show dbs | db.getMongo().getDBs() |
show collections | db.getCollectionNames() |
스크립트를 사용해 셸에 변수를 입력할 수도 있다.
예를들어 보조자 함수를 간단히 초기화하는 스크립트를 구현할 수 도 있다.
$ vim connectTo.js
var connectTo = function(port, dbname) {
if (!port) { port = 27017; }
if (!dbname) { dbname = "test"; }
db = connect("localhost:" + port + "/" + dbname);
return db;
}
:wq!
$ mongo
> typeof connectTo
undefined
> load("connectTo.js")
true
> typeof connectTo
function
스크립트 셸을 실행해 connectTo라는 함수를 초기화하였다.
보조자 함수를 더하는 작업 외에도 자주 하는 작업이나 관리 작업을 자동화하는 데 셸을 사용한다.
기본적으로 셸은 셸을 시작한 디텍터리에서 스크립트를 찾는다.
셸을 시작한 디렉터리가 어디인지 확인하려면 run("pwd") 명령어를 사용해 확인할 수 있다.
> run("pwd")
{"t":{"$date":"2022-05-26T04:42:27.961Z"},"s":"I", "c":"-", "id":22810, "ctx":"js","msg":"shell: Started program","attr":{"pid":"734","argv":["/usr/bin/pwd"]}}
sh734| /
0
스크립트가 현재 디렉터리에 없다면 셸에 상대 또는 절대 경로를 제공하면 된다.
하지만 이 방법은 출력이 이상한 형태로 나타나며 파이프를 지원하지 않기 때문에 제한적으로 사용된다.
.mongorc.js 만들기
셸이 시작할때마다 실행되거나 자주 로드되는 스크립트를 .mongorc.js 파일에 넣을 수 있다.
만약 mongosh로 접속 시에는 .mongoshrc.js의 파일명으로 등록해야 동작한다.
$ cd ~/
$ vim .mongorc.js
var foods = ["pizza", "berger", "chicken"];
var index = Math.floor(Math.random() * 3);
print("today diner is " + foods[index] + "!!");
:wp!
$ mongo
MongoDB shell version v5.0.8
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("5f96ff6c-6a18-4039-af08-c6be80fa731e") }
MongoDB server version: 5.0.8
================
Warning: the "mongo" shell has been superseded by "mongosh",
which delivers improved usability and compatibility.The "mongo" shell has been deprecated and will be removed in
an upcoming release.
For installation instructions, see
https://docs.mongodb.com/mongodb-shell/install/
================
today diner is pizza!!
이 스크립트로 사용하고 싶은 전역 변수를 설정하고, 긴 별칭을 짧게 만들고, 내장 함수를 재정의 한다.
.mongorc.js의 일반적인 용법 중 하나는 더 위험한 셸 보조자를 제거하는 것이다.
dropDatabase나 deleteIndexes 같은 함수를 아무도 실행하지 못하게 재정의하거나 모두 선언 해제한다.
$ vim .mongorc.js
var no = function() {
print("Not on my watch.");
}
// prevent database delete
db.dropDatabase = DB.prototype.dropDatabase = no;
// prevent collection delete
DBCollection.prototype.dtop = no;
// prevent index delete
DBCollection.prototype.dropIndex = no;
DBCollection.prototype.dropIndexes = no;
:wp!
$ mongo
> db.dropDatabase()
Not on my watch.
이는 악의적인 시도로부터 보호 하지는 못하지만 실수는 방지할 수 있다.
셸을 시작할 때 --norc 옵션을 사용해 .mongorc.js의 로딩을 비활성화 할 수도 있다.
프롬프트 커스터마이징하기
기본 셸 프롬프트는 문자열이나 함수에 prompt 변수를 설정해 재정의한다.
마지막 작업이 완료된 시간을 얻으려면 현재 시각을 출력하는 프롬프트를 만들 수 있다.
> prompt = function() {
... return (new Date()) + "> ";
... }
function() {
return (new Date()) + "> ";
}
Thu May 26 2022 05:21:02 GMT+0000 (UTC)>
또는 현재 사용하는 데이터베이스를 보여주는 프롬프트를 만든다.
> prompt = function() {
if (typeof db == "undefined") {
return '(nodb)> ';
}
try {
db.runCommand({getLastError:1});
} catch (e) {
print(e);
}
return db+"> ";
}
function() {
if (typeof db == "undefined") {
return '(nodb)> ';
}
try {
db.runCommand({getLastError:1});
} catch (e) {
print(e);
}
return db+"> ";
}
test>
프롬프트 함수는 문자열을 반환한다는 점을 기억하고, 예외를 잡는 데 주의를 기울여야 한다.
프롬프트가 예외 상황으로 바뀌면 매우 복잡해진다.
일반적으로 프롬프트 함수는 getLastError 호출을 포함해야 한다.
그러면 셸의 연결이 끊겼을 때 쓰기에서의 오류를 감지해서 자동으로 다시 연결해준다.
항상 사용자 정의 프롬프트를 사용하려면 .mongorc.js 파일을 사용할 수 도 있다.
복잡한 변수 수정하기
셸에서 다중행 지원은 다소 제한적이며 이전 행들을 편집할 수 없다.
따라서 코드나 객체 블록이 크면 편집기에서 편집하는 것이 좋다.
emacs 문서 편집기를 사용할 것인데 Docker 컨테이너 안에는 emacs가 설치되어 있지 않기 때문에 먼저 설치해야 한다.
$ apt-get update
$ apt-get install emacs
셸 또는 작업 환경에서 EDITOR 변수를 설정하거나 .mongorc.js 파일에 추가해도 된다.
$ mongo
> EDITOR = "/usr/bin/emacs"
/usr/bin/emacs
이제 edit 명령어를 사용해 명령어나 변수를 편집할 수 있다.
> edit db.logs.findOne({name: "devbeekei"}) # 명령어 수정
> var log = edit db.logs.findOne({name: "devbeekei"})
> edit log # 변수 수정
변경을 완료하고 control + x, control + c, y를 차례대로 누르고 편집기를 종료하게 되면 명령어가 수정되어있거나 변수가 셸에 다시 로그되어 갱신된다.
불편한 컬렉션 명
컬렉션명이 예약어가 아니거나 유효하지 않은 자바스크립트 속성명이 아니라면 db.collectionName 구문으로 컬렉션을 항상 가져올 수 있다.
만약 version이라는 컬렉션에 접근한다고 가정한다면, db.version은 db의 함수이므로 접근할 수 없다.
> db.version
function() {
return this.serverBuildInfo().version;
}
이럴땐 getCollection 함수를 사용하면 접근이 가능하다.
> db.getCollection("version")
test.version
또 다른 방법으로, 배열 접근 구문을 사용해 유효하지 않은 속성명을 피할 수 있다.
자바스크립트에서 x.y는 x["y"]와 동일하므로, 서브컬렉션이 상수 이름 뿐 아니라 변수를 이용해도 접근할 수 있다.
> var cName="logs"
> db[cName].find()
{ "_id" : ObjectId("628f13e9aec5fdd7a4bb19f0"), "name" : "devbeekei", "loginDate" : ISODate("2022-05-26T05:45:13.380Z") }
{ "_id" : ObjectId("628f13edaec5fdd7a4bb19f1"), "name" : "devbeekei2", "loginDate" : ISODate("2022-05-26T05:45:17.975Z") }
{ "_id" : ObjectId("628f13f2aec5fdd7a4bb19f2"), "name" : "devbeekei3", "loginDate" : ISODate("2022-05-26T05:45:22.420Z") }
'MongoDB' 카테고리의 다른 글
몽고DB 도큐먼트 갱신, 치환하기 (0) | 2022.06.03 |
---|---|
몽고DB 도큐먼트 삽입, 삭제하기 (0) | 2022.05.26 |
몽고DB의 데이터형 (0) | 2022.05.25 |
몽고DB 셸 소개 (0) | 2022.05.25 |
Docker로 몽고DB 시작하기 (0) | 2022.05.25 |