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));
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);
})
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);
});
};
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값을 선택하여 채워넣는다.
...
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);
})