Mongo DB 연동 II - mongodb client
이번장에서는 Mongo DB를 연동하기 위해 mongodb 라는 드라이버 모듈을 사용해보겠습니다. mongodb 모듈을 사용하는 이유는 Mongo DB를 마치 Mongo DB 자체콘솔에서 사용하는것처럼 Mongo DB의 명령어들을 그대로 사용할 수 있기 때문입니다.
가.Mongo DB의 데이터 구조
시작에 앞서 Mongo DB의 구조를 먼저 알아보겠습니다.
Mongo DB 는 데이터 베이스를 관리하는 단위를 크게 세 단계로 나눌 수 있는데, 가장 큰 영역인 데이터 베이스를 기준으로, RDB의 Table에 해당하는 Collection, 그리고 각각의 개별 데이터(Record)인 Document 로 구성되어 있습니다.
- Structure of Mongo DB vs RDB
Mongo DB | RDB |
---|---|
Database | Database |
Collection | Table |
Document | Record |
Field | Column (Field) |
나.데이터베이스 접속주소
Mongo DB 에 접속하기 위해서는 데이터베이스의 주소를 값으로 전달하는데 주소의 형태는 아래와 같습니다.
mongodb:// ip address : port / 데이터베이스이름
다.mongodb 모듈 설치
설치에 앞서 먼저 mongodb 드라이버 모듈을 설치합니다.
- npm install mongodb
라.데이터베이스 실행
설치된 Mongo DB를 실행합니다. (Mongo DB 의 설치는 MongoDB 연동 I 을 참조해 주시기 바랍니다.)
- Mongo DB 설치디렉토리/Server/3.4/bin/mongod.exe --dbpath 데이터베이스경로 예) /root/database 또는 c:\database
마.데이터베이스 연결확인
기본이 되는 데이터 베이스 연결코드를 작성해보겠습니다. dbcon.js 파일을 생성하고 아래 코드를 입력합니다.
- dbcon.js
var Client = require('mongodb').MongoClient;
Client.connect('mongodb://localhost:27017/school', function(error, db){
if(error) {
console.log(error);
} else {
console.log("connected:"+db);
db.close();
}
});
node dbcon 을 실행했을때 콘솔에 connected:[Object].. 라는 로그가 출력되면 정상입니다.
바.기초 데이터(Document) 생성
우선 Mongo DB를 조작하기 위해서 먼저 기초 데이터를 입력해 줍니다. insert( ) 함수를 이용해서 한번에 하나씩 입력할 수도 있지만, 여러개의 document 를 한번에 입력할 수도 있습니다.
1. 데이터 한개(Single Document) 입력
- dbinsert.js
var Client = require('mongodb').MongoClient;
Client.connect('mongodb://localhost:27017/school', function(error, db){
if(error) {
console.log(error);
} else {
// 1. 입력할 document 생성
var michael = {name:'Michael', age:15, gender:'M'};
// 2. student 컬렉션의 insert( ) 함수에 입력
db.collection('student').insert(michael);
db.close();
}
});
2. 데이터 여러개(Multi Documents) 입력
- dbinsertMany.js
var Client = require('mongodb').MongoClient;
Client.connect('mongodb://localhost:27017/school', function(error, db){
if(error) {
console.log(error);
} else {
// 1. 입력할 documents 를 미리 생성
var jordan = {name:'Jordan', age:16, gender:'M'};
var amanda = {name:'Amanda', age:17, gender:'F'};
var jessica = {name:'Jessica', age:15, gender:'F'};
var james = {name:'James', age:19, gender:'M'};
var catherine = {name:'Catherine', age:18, gender:'F'}
// 2. insertMany( ) 함수에 배열 형태로 입력
db.collection('student').insertMany([jordan,amanda,jessica,james,catherine]);
db.close();
}
});
에러메시지가 출력되지 않으면 둘다 정상적으로 입력된겁니다.
사. 데이터 읽기
이번에는 위에서 입력한 데이터를 읽어오는 코드를 작성해 보겠습니다.
1. find( ) 함수를 이용한 전체 데이터 읽어오기
var Client = require('mongodb').MongoClient;
Client.connect('mongodb://localhost:27017/school', function(error, db){
if(error) {
console.log(error);
} else {
// 1. find( ) 함수에 아무런 입력값이 없으면 컬렉션의 전체 document 를 읽어온다.
var cursor = db.collection('student').find();
// 2. 읽어온 document 를 cursor 에 넣고 반복처리
cursor.each(function(err,doc){ // document 가 예약어이기 때문에 변수명을 doc로 변경
if(err){
console.log(err);
}else{
if(doc != null){
// 3. document 가 정상적으로 있으면 console 에 출력해준다.
console.log(doc);
}
}
});
db.close();
}
});
2. Query 로 특정데이터 읽어오기
Mongo DB가 Nosql 이긴 하지만 데이터를 검색할때는 query를 해야지만 가져올 수 있습니다. 위의 예제에서처럼 query 가 없으면 전체 데이터를 읽어옵니다.
var Client = require('mongodb').MongoClient;
Client.connect('mongodb://localhost:27017/school', function(error, db){
if(error) {
console.log(error);
} else {
// 1. 읽어올 document 필드값 정의
var query = {gender:'M'};
// 2. find( ) 함수에 query 입력
var cursor = db.collection('student').find(query);
cursor.each(function(err,doc){
if(err){
console.log(err);
}else{
if(doc != null){
console.log(doc);
}
}
});
db.close();
}
});
3. Field Projection 으로 특정필드만 가져오기
데이터를 가져올 때 Document 내에 있는 Field 의 개수가 너무 많으면 데이터 용량이 늘어나게 되므로 필요한 Field 만 선택해서 가져올 수 있는데 이것을 Projection 이라고 합니다.
var Client = require('mongodb').MongoClient;
Client.connect('mongodb://localhost:27017/school', function(error, db){
if(error) {
console.log(error);
} else {
// 1. 쿼리작성
var query = {gender:'M'};
// 2. 읽어올 Field 선택
var projection = {name:1,age:1,_id:0};
// 3. find() 함수에 작성된 query와 projection을 입력
var cursor = db.collection('student').find(query,projection);
cursor.each(function(err,doc){
if(err){
console.log(err);
}else{
if(doc != null){
console.log(doc);
}
}
});
db.close();
}
});
프로젝션 사용시에 주의할 점은 기본 필드인 _id 필드를 제외하고는 필드선택 여부가 모두 동일해야 합니다.
var prj1 = {name:1, age:1}; // O 가능 - name,age 필드만 가져온다.
var prj2 = {name:0, age:0}; // O 가능 - name,age 필드를 제외하고 가져온다.
var prj3 = {name:1, age:0}; // X 불가능 - 오류발생
4. $gt(greater than) $lt(less than) 사용하기
$gt, $lt 등의 Mongo DB 명령어를 사용해서 검색 범위를 특정할 수 있습니다.
var Client = require('mongodb').MongoClient;
Client.connect('mongodb://localhost:27017/school', function(error, db){
if(error) {
console.log(error);
} else {
// 1. gender 가 'F' 이면서 age 가 16보다 크고 19보다 작은 값 선택
var query = {gender:'F', age:{'$gt':16,'$lt':19}};
var cursor = db.collection('student').find(query);
cursor.each(function(err,doc){
if(err){
console.log(err);
}else{
if(doc != null){
// 2. 출력할 document 에서 name 필드만 출력
console.log('student name:'+doc.name);
}
}
});
db.close();
}
});
5. Paging 처리
데이터를 처리하다보면 document 의 개수가 많아서 paging 처리를 해야될 경우가 있는데 아래와 같이 skip( ) 함수와 limit( ) 함수를 함께 사용해서 처리할 수 있습니다.
var Client = require('mongodb').MongoClient;
Client.connect('mongodb://localhost:27017/school', function(error, db){
if(error) {
console.log(error);
} else {
var query = {}
// 1. skip - 선택된 document 중에서 건너뛸 개수
// 2. limit - 선택된 document 중에서 skip 다음 부터 가져올 개수
// 현재 document 의 개수가 6개이면 2개를 건너띄고 3번째 부터 2개(3번과 4번)를 가져온다.
var cursor = db.collection('student').find(query).skip(2).limit(2);
cursor.each(function(err,doc){
if(err){
console.log(err);
}else{
if(doc != null){
console.log(doc);
}
}
});
db.close();
}
});
아. 데이터 수정
update 함수를 사용해서 데이터를 수정할 수 있습니다. update 함수는 3개의 인자를 입력받는데, 검색대상을 선택하는 query, 실제수정할 데이터정보인 operator, 그리고 수정처리에 대한 option 을 설정해서 입력하면 됩니다.
var Client = require('mongodb').MongoClient;
Client.connect('mongodb://localhost:27017/school', function(error, db){
if(error) {
console.log(error);
} else {
// 1. 수정 대상 쿼리
var query = {name:'Michael'};
// 2. 데이터 수정 명령 : set 명령을 사용하면 특정 field의 값만 변경할 수 있음
var operator = {name:'Joe', age:15, gender:'M'};
// 3. 수정 옵션 : upsert 가 true 일 경우 query 대상이 존재하면 update, 없으면 insert 처리
var option = {upsert:true};
db.collection('student').update(query,operator,option,function(err,upserted){
if(err){
console.log(err);
}else{
console.log('updated successfully!');
}
});
db.close();
}
});
자. 데이터 삭제
remove 함수로 특정 document를 삭제할 수 있습니다.
var Client = require('mongodb').MongoClient;
Client.connect('mongodb://localhost:27017/school', function(error, db){
if(error) {
console.log(error);
} else {
// 1. 삭제할 대상 쿼리
var query = {name:'Joe'};
// 2. remove 함수에 입력
db.collection('student').remove(query,function(err,removed){
if(err){
console.log(err);
}else{
console.log('removed successfully!');
}
});
db.close();
}
});