몽구스(mongoose) 제대로 활용하기 1
Instance method
몽구스의 인스턴스 메소드는 몽구스 스키마(Schema)를 정의할 때 해당 스키마로 만든 모델(Model)의 인스턴스에서 사용할 메소드를 정의하는 것이다. 입력값을 도큐먼트의 프로퍼티와 비교한 결과를 리턴하는 인스턴스 메소드를 만든다고 한다면 다음과 할 수 있다.
const mongoose = require('mongoose');
const personSchema = new mongoose.Schema({
name: String,
age: Number
});
// this는 document를 가리킨다.
personSchema.methods.isSameAge = function(age) {
return this.age === age ? true : false
}
위에서 person 스키마의 인스턴스 메소드로 정의한 introduce는 다음과 같이 모델의 인스턴스인 도큐먼트(Document)에서 사용할 수 있다.
const PersonModel = mongoose.model("Person", personSchema);
const person = new PersonModel({
name: "Kim",
age: 26
})
person.isSameAge(26) // true
Middleware
몽구스의 미들웨어는 pre, post hook 이라고도 불리고 몽구스 함수의 실행 전후에 실행되게 된다. 미들웨어의 종류는 document, query, aggregate, model 미들웨어로 총 4가지가 있다. 모든 미들웨어에 pre(), post() 훅을 사용할 수 있기 때문에 원하는 메소드의 전 후 작업이 있을 경우 미들웨어를 사용하면 유용하다. 이 중 가장 활용도가 높은 document 미들웨어와 query 미들웨어에 대해 알아보자.
document middleware
도큐먼트 미들웨어에서의 this는 도큐먼트를 가리키고 다음 도큐먼트 메소드들에서 사용이 가능하다.
- validate
- save
- remove
- updateOne
- deleteOne
- init
pre() 메소드는 지정한 함수가 실행되기 전에 도큐먼트 또는 쿼리에서 처리할 일이 있을 때 사용할 수 있다. 다른 미들웨어가 있는 경우 next를 호출하면서 다음 미들웨어를 호출할 수 있다. 예를들어 사용자의 비밀번호를 저장하기 전에 암호화 해야하는 상황이라면 다음과 같이 사용할 수 있다.
// bcrypt 모듈을 이용해 비밀번호를 암호화
personSchema.pre('save', async function(next) {
this.password = await bcrypt.hash(this.password, 10)
next()
})
post 메소드는 데이터베이스에 도큐멘트에 지정한 메소드가 실행된 이후에 호출된다.
personSchema.post('save', function() {
console.log(`${this} is saved`)
})
query middleware
쿼리 미들웨어에서의 this는 쿼리를 가리킨다.
쿼리 미들웨어에서의 this는 쿼리를 가리키고 다음 모델, 쿼리 메소드에서 사용이 가능하다.
- count
- deleteMany
- deleteOne
- find
- findOne
- findOneAndDelete
- findOneAndRemove
- findOneAndUpdate
- remove
- update
- updateOne
- updateMany
쿼리 메소드를 쿼리 미들웨어에서 사용할 수 있다.
personSchema.pre('findOneAndUpdate', async function (next) {
this.getUpdate()
this.setUpdate(...)
...
next()
})
미들웨어 팁
model.create()는 모든 도큐먼트에 대해서 save훅을 실행한다.
findById(And…) 메소드는 findOne(And…) 훅을 실행한다.
remove훅은 기본적으로 도큐먼트 미들웨어에 적용된다. 쿼리 미들웨어에 적용하려면 다음처럼 해야한다.
schema.pre('remove', { document: false, query: true })
updateOne, deleteOne훅은 기본적으로 쿼리 미들웨어에 적용된다. 도큐먼트 미들웨어에 적용하려면 다음처럼 해야한다.
schema.pre('updateOne', { document: true, query: false })