본문 바로가기

Study/Mongo & Mongoose

Schema

Validation

mongoose는 shema를 정의할 때 전달받은 조건을 자동으로 검사해주는 built in validation(내장 유효성 검사)을 제공한다. 

 

const productShema = new mongoose.Schema({
  name: {
    type: String,
    required: true,
  },
  price: {
    type: Number,
    required: true,
    min: 0, // or min: [0, 'set price positive'] => 두번째 아이템을 에러메세지로 전달
  },
  onSale: {
    type: Boolean,
    default: false,
  },
  categories: {
    type: [String],
    default: ['cycling']
  }
});

const Product = mongoose.model('Product', productShema);

const bike = new Product({
  name: 'Mountain Bike',
  price: 499,
  color: 'red' // color 속성은 db에 저장되지 않는다 
});

bike
  .save()
  .then((data) => console.log(data))
  .catch((err) => console.log(err));

 

  1. validation에 사용할 수 있는 조건들 
    • type | 해당 property의 데이터 타입을 설정
      • 데이터 타입에 따라 추가로 사용할 수 있는 조건도 있다(ex. String => maxlength, Number => min)
      •  enum: [ ] 을 조건 검사에 넣으면, 해당 property의 값은 배열에 전달된 값 중 하나여야 한다. 
    • required | 해당 property를 반드시 전달받아야 하는지, 아닌지를 설정 
    • default | 해당 속성의 값이 전달되지 않았을 때 기본으로 할당할 값을 설정 
  2. shema에 등록되지 않은 속성을 추가하면 error가 발생하지는 않지만, 해당 속성은 db에 추가되지 않고 무시된다. 
  3. insertMany를 이용해서 한 번에 여러 개의 데이터를 저장할 때, 유효성 검사를 통과하지 못한 데이터가 하나라도 있으면, 배열에 전달되는 데이터 전부를 저장하지 못한다. 
  4. 인스턴스가 추가된 후에는 유효성 검사가 실행되지 않는다.
    • 예를 들어 db에 추가된 후에는, price를 음수로 update해도 error가 발생하지 않는다. 
    • findAndUpdate와 같은 함수에 { runValidators: true } 옵션을 전달하면, 데이터를 수정할 때에도 유효성 검사를 실행할 수 있다. 

Shema.methods/ statics 

instance level | ex) new Product( {...} ).save 

const productShema = new mongoose.Schema({ ... });

productShema.methods.toggleOnSale = function () {
  this.onSale = !this.onSale; 
  return this.save();  
};

// schema methods 정의한 후에 model 정의해야 됨
// model 만들고 method 만드는 거 안됨 
const Product = mongoose.model('Product', productShema); 

const findProduct = async function(productName) {
  const foundProduct = await Product.findOne({name: productName});
  await foundProduct.toggleOnSale();
  console.log(foundProduct);
}

 

  • save나 find와 같이 데이터베이스에서 무언가를 찾고 저장하는 등의 함수들은 시간이 오래 걸리는 함수(asynchronous operation)로, thenable object를 반환한다. 
  • instance level 함수에서 this는 collection의 개별 데이터(인스턴스)를 가리킨다. 

static level | ex) Product.find 

// ...
productShema.statics.fireSale = function () {
  return this.updateMany({}, { onSale: true });
};

const Product = mongoose.model('Product', productShema);
// ...
Product.fireSale()
  .then(res => console.log(res));

 

  • static level에서 this는 collection 자체를 가리킨다. 

Shema.virtuals | getter & setter 

데이터베이스에는 존재하지 않는 property를 shema에 추가하면, mongoose를 사용해 해당 property를 이용할 수 있다. 

 

const personShema = new mongoose.Schema({
  first: String,
  last: String,
});

personShema
  .virtual('fullName') 
  .get(function () {
    return `${this.first} ${this.last}`;
  }) 
  .set(function (value) {
    this.first = value.substr(0, value.indexOf(' '));
    this.last = value.substr(value.indexOf(' ') + 1);
  });

const Person = new mongoose.model('Person', personShema);

// const tammy = new Person({first: 'Tammy', last: 'Chow'});
// tammy.fullName; => getter
// tammy.fullName = 'Tammy Xiao' => setter

 

  • set의 콜백 함수의 인자 value는 fullName에 할당하는 값이 된다. 위의 예제에서 value는 'Tammy Xiao'가 된다. 

Shema.pre/ post | middleware

특정 method가 실행되기 이전(pre)이나 이후(post)에 실행할 코드를 설정할 수 있다. 예를 들어 어떤 컬렉션에 데이터가 저장(save)되기 이전이나 이후에 실행할 함수를 정의할 수 있다. 

 

+) Model에 middleware를 설정하는 것도 가능하다. 예를 들어 컬렉션의 데이터를 업데이트하기 이전이나 이후에 실행할 함수를 정희할 수 있다.  

'Study > Mongo & Mongoose' 카테고리의 다른 글

what is Mongoose?  (0) 2022.06.06
what is BSON?  (0) 2022.06.04
Mongo shell  (0) 2022.06.04