mongosh는 Node.js REPL (Read Eval Print Loop) 환경에서 돌아가는 쉘이라고 보면 됨.
그러니까 JS 문법을 기반으로 node.js 어지간한 건 다 쓸 수 있고 심지어는 npm 모듈까지 쓸 수 있어서 잘만 쓰면 엄청 편함.
당장 쉘에서 여러 라인을 사용하려면 외부 에디터나 내장 에디터를 쓰면 되고,
// 외부 에디터
edit
// 내장 에디터
.editor
여기선 파일로 만들어서 실행시키는 것 위주로 설명함.
test.js 라는 파일을 만들어 놓고,
print('hello world');
mongosh에서 실행시키려면 load()를 사용하면 됨.
[direct: mongos] mydb> load('/PATH/TO/test.js')
hello world
true
DB에 값 넣고 빼고 다 할 수 있음.
test.js를 아래처럼 수정하고,
mydb = db.getSiblingDB('mydb');
mydb.mycol.insertMany([
{
name: '백충덕',
lv: 1
},
{
name: '조조',
lv: 99
}
]);
mongosh에서 실행시킨 후 실제로 query해보면 그대로 들어있는 것 확인 가능.
[direct: mongos] mydb> load('/PATH/TO/test.js')
true
[direct: mongos] mydb> db.mycol.find()
[
{ _id: ObjectId('65dd80e2b958ad4033168f4b'), name: '백충덕', lv: 1 },
{ _id: ObjectId('65dd80e2b958ad4033168f4c'), name: '조조', lv: 99 }
]
load() 할 때 상대경로로도 가능한데 mongosh를 실행한 현재경로로부터의 상대경로이며 mongosh에선 아래처럼 확인 가능
// node.js를 그대로 쓸 수 있다
[direct: mongos] mydb> process.cwd()
/PATH/TO
// test.js 절대경로가 /PATH/TO/test.js 이고 현재경로가 /PATH/TO 이므로 아래처럼 load()도 가능
[direct: mongos] mydb> load('test.js')
node.js를 그대로 쓸 수 있어서 실행결과를 파일로 저장도 가능.
사실 여기서부터 활용도가 넘사벽.
test.js를 아래처럼 수정해서 아까 넣은 데이터를 가져와 파일로 저장.
mydb = db.getSiblingDB('mydb');
const filePath = '/PATH/TO/mycol.json';
mydb.mycol.find().forEach((doc)=>{
// fs는 built-in 모듈이라 require() 안하고 그냥 써도 됨
require('fs').appendFileSync(filePath, JSON.stringify(doc)+'\n');
});
이걸 mongosh에서 load('/PATH/TO/test.js') 로 실행시킨 후 /PATH/TO/mycol.json 파일을 열어보면 직전에 insert 했던 doc들이 한줄씩 저장되어 있는 것을 확인 가능.
cat /PATH/TO/mycol.json
{ _id: ObjectId('65dd80e2b958ad4033168f4b'), name: '백충덕', lv: 1 }
{ _id: ObjectId('65dd80e2b958ad4033168f4c'), name: '조조', lv: 99 }
npm 모듈도 다 사용할 수 있으니까 활용도는 무궁무진함.
npm은 global로 설치된 것, 혹은 current working directory의 node_modules에 설치된 것을 사용 가능.
// 테스트용으로 date-fns 설치
cd /PATH/TO
npm install date-fns --save
// test.js
// process.cwd()를 통해 확인하고 process.chdir()로 cwd를 맞게 변경을 해도 require()가 안되길래 그냥 절대경로로 지정했음...
const dateFns = require('/PATH/TO/test.js');
print(dateFns.format(new Date(), 'yyyy-MM-dd'));
// mongosh
[direct: mongos] mydb> load('/PATH/TO/test.js')
2024-02-27
위에서 적은 것처럼 mongosh 안에서 불러서 사용할 수도 있지만,
실제로는 커맨드라인에서 실행해서 필요한 명령들을 실행하거나 데이터를 수집하는 용도로 쓰기 좋음.
그러려면 mongosh의 js 파일을 로드하기 위한 --file 혹은 -f 옵션과 접속/인증을 하지 않는 --nodb 옵션으로 실행하고,
스크립트 내부에서 접속 및 인증을 처리하는 방식이 필요함.
아래는 특정 DB의 컬렉션별 docs 카운트를 한 번에 출력해 볼 수 있는 예제.
/PATH/TO/docs_count.js
// config DB와 docs 카운트 출력을 원하는 DB에 모두 접근할 수 있는 사용자 인증을 하거나 혹은 각각 인증 필요
// 여기선 그냥 root 권한 사용자로 인증한다고 가정함
const user = 'root';
const pwd = encodeURIComponent('비밀번호');
const conn = Mongo(`mongodb://${user}:${pwd}@HOSTNAME:PORT`);
const db_config = conn.getDB('config');
const DB_NAME = 'mydb';
const db_mydb = conn.getDB(DB_NAME);
db_config.collections.find().forEach((col) => {
if (col._id.indexOf(DB_NAME + '.') !== 0) return;
const colName = col._id.split('.')[1];
const cnt = db_mydb.getCollection(colName).estimatedDocumentCount();
print(`${colName} = ${cnt}`);
});
이 스크립트를 아래처럼 호출하면 mydb의 컬렉션별 docs 카운트가 출력됨.
/DB_PATH/bin/mongosh --nodb -f /PATH/TO/docs_count.js
Current Mongosh Log ID: 65dd8ed336cfbfea538f1f0e
Loading file: scripts/test.js
my_col = 633
my_col2 = 717
my_col3 = 1564
mongosh에서 매번 입력해야 했던 저런 단발성 정보확인용 스크립트는 .mongoshrc.js에 snippet처럼 만들어서 호출해도 좋고,
그 외에 주기적으로 실행해서 데이터를 모으거나 하는 용도로도 일일이 뭔가 따로 만들 필요없이 mongosh 실행만으로 가능하니까 활용처는 다양할 듯.
[참고]
https://www.mongodb.com/docs/mongodb-shell/write-scripts/
'DataBase' 카테고리의 다른 글
[MongoDB] chunk 관리 (0) | 2024.07.04 |
---|---|
[MongoDB] oplog 분석 (0) | 2024.05.29 |
[MongoDB] mongosh editor (0) | 2024.02.20 |
[MongoDB] .mongoshrc.js (0) | 2024.02.19 |
[MongoDB] Schema Validation (스키마 유효성 검사) (0) | 2023.07.19 |