mongoose 개요

brandon·2023년 6월 13일

NoSQL

목록 보기
4/4

0. setup

Mongoose 는 Object-Document Mapper(ODM)이다.

npm i --save mongoose

다운 받은 후 app.js에서 import 한다.

const mongoose = require('mongoose');

mongoose.connect(connection string)
    .then(result => {
        app.listen(3000);
    })
    .catch(err => console.log(err));

1. Create Schema & Instance save

Mongoose에서는 반복되는 구조는 Schema를 사용할 수 있다. required:를 통하여 NoSQL의 flexibility가 보장된다.

product.js

const mongoose = require('mongoose');
const Schema = mongoose.Schema; 

const productSchema = new Schema({
  title: {
    type: String, 
    required: true
  },
  price: {
    type: Number, 
    required: true
  },
  description: {
    type: String, 
    required: true
  },
  imageUrl: {
    type: String, 
    required: true
  }
});

Product instance를 만들때는 Js Object 처럼 만들되 parameter에 Object를 넣으면 된다.

shopController.js

exports.postAddProduct = (req, res, next) => {
  const title = req.body.title;
  const imageUrl = req.body.imageUrl;
  const price = req.body.price;
  const description = req.body.description;
  const product = new Product({
    title: title, 
    price: price, 
    description: description,
    imageUrl: imageUrl
  });
};

document를 생성할때는 mongoose built-in function save()를 사용하면 된다.

  product.save()
    .then(result => {
      console.log('created product!');
      res.redirect('/admin/products');
    }).catch(err => {
      console.log(err);
    })

2. Read / Update / Delete document

find()는 mongodb때 처럼 존재하지만 cursor를 반환하지 않고 바로 document를 반환한다.
find()또 이미 저장되어있는 mongoose object에 할 경우 update만 한다.

findById()도 built-in으로 저장 되어있다.

findByIdAndDelete()로 삭제할 수 있다.

update:

exports.postEditProduct = (req, res, next) => {
  const prodId = req.body.productId;
  const updatedTitle = req.body.title;
  const updatedPrice = req.body.price;
  const updatedImageUrl = req.body.imageUrl;
  const updatedDesc = req.body.description;
  Product.findById(prodId)
    .then(product => {
      product.title = updatedTitle;
      product.description = updatedDesc; 
      product.price = updatedPrice; 
      product.imageUrl = updatedImageUrl; 
      return product.save()
    })
    .then(result => {
      console.log('product edited!');
      res.redirect('/admin/products');
    })
    .catch(err => {
      console.log(err);
    });
};

3. Populate()

Product에 생성자 userId field를 넣는다고 해보자.

const productSchema = new Schema({
  ...
  userId: {
    type: Schema.Types.ObjectId,
    ref: 'User',
    required: true
  }
});
adminController/postAddProduct

exports.postAddProduct = (req, res, next) => {
  const title = req.body.title;
  const imageUrl = req.body.imageUrl;
  const price = req.body.price;
  const description = req.body.description;
  const product = new Product({
    title: title,
    price: price,
    description: description,
    imageUrl: imageUrl,
    userId: req.user // ref:'User' 덕분에 _id값을 자동으로 읽는다.
  });
  product
    .save()
    ...

만약 getProducts 에서 user에 관한 정보가 필요할땐 populate()를 사용할 수 있다.

exports.getProducts = (req, res, next) => {
  Product.find()
    .populate('userId', 'email')//email값을 선택하여 채워넣는다.
    ...

4. Model Methods

custom model methods를 만들 수 있다.

const userSchema = new Schema({
  ...
});


userSchema.methods.addToCart = function(product) {
  ...
}

이렇게 만들면 controller에서 user instance를 통해 addToCart method 를 사용 할 수 있다.

exports.postCart = (req, res, next) => {
  const prodId = req.body.productId;
  Product.findById(prodId)
    .then(product => {
      return req.user.addToCart(product);
    })
profile
everything happens for a reason

0개의 댓글