2022. 3. 17. 18:45ㆍBACK END/NODE.JS
Mongoose는 MongoDB 기반 ODM(Object Data Mapping) Node.JS 전용 라이브러리로, ODM은 데이터베이스와 객체지향 프로그래밍 언어 사이 호환되지 않는 데이터를 변환하는 프로그래밍 기법이다. 즉 MongoDB 에 있는 데이터를 Application에서 JavaScript 객체로 사용 할 수 있도록 해준다.
설치는 상단 배너 클릭!
MongoDB 알아보기
1. Document
Document는 RDBMS에서의 Row(혹은 튜플)과 동일한 개념. 예를 들어 아래와 같은 JSON 형태의 key-value 쌍으로 이루어진 데이터 구조를 하나의 Document라고 보면 된다.
{
"_id": "60865be6dc8e3f41f861b29c"
"username": "이름",
"password": "비밀번호",
}
각 Document는 _id를 갖고 있는데 이 값은 유일하다. Primary Key랑 비슷한 개념.
2. Collection
Collection은 Document의 그룹이다. RDBMS로 따지자면 Table과 비슷한 개념. 다만 위에서 말했듯이 스키마를 가지고 있지 않다.
3. Database
Database는 Collection들의 물리적인 컨테이너이자 가장 상위 개념이다. RDBMS에서의 Database와 동일하다.
Mongoose란?
Mongoose 사용하기MongoDB ODM 중 가장 유명한 라이브러리
데이터베이스 연결, 스키마 정의, 스키마에서 모델로 변환, 모델을 이용해 데이터를 다룸
프로미스와 콜백 사용가능
ODM
ODM : Object Document Mapping.
객체와 문서를 1대 1로 매칭. 즉, MongoDB에 있는 데이터를 NodeJS에서 Javscript 객체로 사용할 수 있도록 해줌.
Mongoose를 활용하여 MongoDB에 로그 기록하기
Mongoose 설치
npm install mongoose --save
1단계. 연결
Mongoose 모듈 활용하여 커넥션 풀, 스키마, 모델을 만들어주어야 함.
함수명 | 설명 |
connect() | mongoose 사용하여 데이터베이스에 연결. 연결 후 mongoose.connection 객체를 사용해 연결 관련 이벤트 처리 가능 |
Schema() | 스키마 정의하는 생성자 |
model() | 모델 정의 |
mongodb.js
require("dotenv").config();
const mongoose = require("mongoose");
var mconn = () =>{
mongoose.connect(process.env.MongoDB, {
useNewUrlParser: true,
useCreateIndex: true,
useUnifiedTopology: true,
})
.then(() => {
console.log("Connected to MongoDB");
})
.catch((err) => {
console.log(err);
});
}
exports.mconn = mconn;
js파일을 만들어 mongoose를 통한 커넥션 풀을 위와 같이 구성한다. .env에 MongoDB의 접속 정보가 저장되어 있음.
2단계. 스키마 생성
Mongoose를 활용하여 스키마를 정의해줄 수 있음. 컬렉션에 들어가는 문서 내부의 각 필드가 어떤 식으로 되어있는지 정의. JSON 객체로 각 속성에 적합한 스키마 옵션과 타입을 지정. 주요 옵션으로 type, required, unique, default 등이 있으며 validate 같은 유용한 옵션들도 있으니 공식문서에서 확인.
공식문서: (mongoosejs.com/docs/schematypes.html)
스키마 옵션 | 설명(구체적 타입 지정) |
type | 자료형 지정 |
required | 반드시 들어가야하는 속성인가? |
unique | 유일한 값이 들어가야 하는 속성인가? |
default | 기본값 |
자료형 | 설명 |
String | 문자열 |
Number | 숫자 |
Boolean | 이진 |
Array | 배열 |
Buffer | 버퍼(Binary Data) |
Date | 날짜 |
ObjectId | 각 문서마다 만들어지는 ObjectId |
Mixed | 혼합 |
스키마와 모델들을 모아놓을 폴더를 생성하고 그 안에 log.js를 추가한 후 아래와 같이 스키마를 생성
model/log.js
const mongoose = require("mongoose");
// 스키마 생성
const LogSchema = new mongoose.Schema({
user: {
type: String,
required: true
},
api: {
type: String,
required: true
},
ip: {
type: String,
required: true
},
dateTime: {
type: Date,
required: true,
default: Date.now,
},
});
//후략
3단계. 모델 생성
모델은 스키마를 사용하여 만든 인스턴스로 데이터베이스에서 실제 작업을 처리할 수 있는 함수들을 지니고 있는 객체.
model/log.js
//(전략)
// 모델 생성
const Log = mongoose.model("Log", LogSchema);
module.exports = Log;
mongoose.model() 에 특정 컬렉션이 사용할 스키마를 지정, 모듈화하여 반환
4단계. 객체 생성
생성한 모델을 참조하여 로그 기록에 사용될 객체를 생성한다. 하나의 Document가 될 데이터임
var Log = require('../model/log'); //경로 확인 필
//중략
//각 변수에 값을 담아준 후
var Data = {
user: user,
api: api,
ip: ip
};
var logData = new Log(Data);
5단계 저장
모델 객체 또는 모델을 사용해서 만들어 낸 인스턴스 객체에는 데이터베이스의 컬렉션에 들어 있는 문서 객체를 조회, 수정, 삭제할 수 있는 메소드가 들어 있다.
함수이름 | 설명 |
find() | 컬렉션 데이터 조회, 콜백 함수로 조회 결과 전달 |
save() | 모델 인스턴스 객체의 데이터 저장, 콜백 함수로 저장 결과 전달 |
update() | 컬렉션 데이터 조회 후 업데이트, where 메소드와 함께 사용됨 |
remove() | 컬렉션 데이터 삭제 |
save() 함수로 저장하고 MongoDBCompass를 통해 확인할 수 있다.
logData.save();
이 때 스키마에서 지정하지 않은 '__v:'라는 필드를 확인할 수 있는데, 이는 버전키로 비활성화시키기 위해 스키마를 생성하는 코드에서 아래와 같이 versionKey: false를 추가해주어야 한다.
const mongoose = require("mongoose");
// 스키마 생성
const LogSchema = new mongoose.Schema({
//------중략-------
},{
versionKey: false
});
추가!!(배열 Update)
위 방법으로 액션별 로그를 남길 수 있으나 보다 체계적인 로그 관리를 위해 아래와 같이 [날짜>사용자>log]의 형식으로 레벨을 나누어 사용자별 log배열 형태로 저장하고자 함.
//날짜별
user:(유저명)
log:[{api, ip, value, dateTime}]
model/log.js
// model/log.js
const mongoose = require("mongoose");
var moment = require('moment')
// const validator = require("validator");
// 스키마 생성
const LogSchema = new mongoose.Schema({
user: {
type: String,
},
log: [{
api: {
type: String,
},
ip: {
type: String,
},
value: {
type: String,
},
dateTime: {
type: Date,
default: Date.now,
},
}]
}, {
versionKey: false
});
// 모델 생성
const Log = mongoose.model(moment().format('YYYY-MM-DD'), LogSchema);
module.exports = Log;
먼저 model/log.js 에서 스키마의 요소를 수정해주어야 함. 그리고 날짜별로 컬렉션을 구분하기 위해 모델 생성시 moment모듈을 활용하여 현재 날짜를 입력함.
Update를 위한 여러 방법
1. in-memory update
const targetAccount = await this.findById(accountObjId).exec();
targetAccount.transactions.push(transactionObjId);
await targetAccount.save();
find를 해서 가져온 도큐먼트를 update한 후 save하는 방식이다. 이 방식은 도큐먼트를 가져온 후, save가 되기 전에 다른 쿼리에 의해 도큐먼트가 변경될 수 있다.
2. Update
PersonModel.update(
{ _id: person._id },
{ $push: { friends: friend } },
done
);
첫 번째 인자로 필터를 넣어주고, 두 번째 인자로 실행할 도큐먼트를 입력해주면 된다. findOneAndUpdate와 다른 점은 findOneAndUpdate는 도큐먼트를 리턴해주지만, update는 도큐먼트를 리턴하지 않는다.
3. findByIdAndUpdate
this.findByIdAndUpdate(accountObjId, {
$push: { transactions: transactionObjId },
}).exec();
4. findOneAndUpdate() -이걸로 진행
// var logData = new Log(Data);
// logData.save();
var log = {
api: api,
ip: ip,
value: value,
}
Log.findOneAndUpdate({ 'user': user }, { $push: { log: log } }, { upsert: true }).exec();
save()함수를 사용하여 입력할 때는 Log모델에 Data객체를 실어 logData라는 인스턴스를 활용했다면
수정에 사용할 findOneAndUpdate함수의 요소로 넣어주기 위해 Log모델 자체를 불러옴
$push operator
배열에 값을 추가한다. 이 방식으로 id에 해당하는 도큐먼트를 찾아서 createdEvents 배열에 eventId를 추가할 수 있게 된다.
exec
query문을 호출한다고 실제적으로 실행되는 것은 아님. 콜백 함수의 유무에 따라 실행 여부가 달라짐. 콜백 함수가 있으면 실행이 되고, 없으면 쿼리를 리턴함. '.exec'로 실행 시켜줌
A.findOneAndUpdate(id, update, options, callback) // executes
A.findOneAndUpdate(id, update, callback) // executes
A.findOneAndUpdate(id, update, options) // returns Query
A.findOneAndUpdate(id, update) // returns Query
A.findOneAndUpdate() // returns Query
Upsert option
upsert를 true로 주면, document가 있으면 update를 하고, 없으면, filter와 update를 결합하여 생성한다.
오늘 날짜로 컬렉션이 생성되고 한 명의 user에 모든 log가 기록된다.
참고
Mongoose 활용하여 Array에 Add(Push), Delete(Remove) 하기
nesoy.github.io
Riyas TK이 몽구스 스키마가 var ContactS
www.javaer101.com
Mongoose Atomic Update 방식을 찾아서
Account 컬렉션은 transaction 도큐먼트의 objectId를 자신의 필드인 transactions에 추가하여야 한다. 그 과정은 다음 두 가지 일을 해야 한다. Account Object Id로 Account 도큐먼트를 찾는다. 그 도큐먼트의 trasa
velog.io
'BACK END > NODE.JS' 카테고리의 다른 글
replace함수로 string타입 데이터 가공 (0) | 2022.03.17 |
---|---|
cross-env (0) | 2022.03.17 |
Bcrypt 암호화 (0) | 2022.03.17 |
REST 미지원 메서드 처리 (0) | 2022.03.17 |
Express-generator를 이용한 express 기본 구조 생성 (0) | 2022.03.17 |