Mongoose(몽구스)에서 populate을 사용하면 다른 Collection에 있는 documents의 ObjectId를 이용하여 documents 참조가 가능하다.
조금 더 보충하자면 MongoDB 자체에서 Documents 마다 자동으로 만들어주는 고유값인 ObjectId가 있는데 다른 Collection에서 populate 메서드를 사용해서 하나의 Documents에 또 다른 Documents의 정보들을 같이 담을 수 있게 해준다.
example)
User.js (Model)
const mongoose = require("mongoose");
const bcrypt = require("bcrypt");
const saltRounds = 10;
const jwt = require("jsonwebtoken");
const userSchema = mongoose.Schema({
email: {
type: String,
unique: 1,
},
name: {
type: String,
},
nickname: {
type: String,
unique: 1,
},
password: {
type: String,
minlength: 6,
},
eventAgreement: {
type: Boolean,
},
createdAt: {
type: Number,
},
google: {
type: String,
},
github: {
type: String,
},
profile: {
type: String,
},
token: {
type: String,
},
tokenExp: {
type: Number,
},
});
.... 생략
ShoppingBasket.js (Model)
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const shoppingBasketSchema = mongoose.Schema(
{
writer: {
type: Schema.Types.ObjectId,
ref: "User",
},
userFrom: {
type: String,
},
title: {
type: String,
maxlength: 50,
},
description: {
type: String,
},
duration: {
type: String,
},
thumbnail: {
type: String,
},
genre: {
type: String,
},
filePath: {
type: String,
unique: 1,
},
cost: {
type: Number,
},
},
{ timestamps: true }
);
const ShoppingBasket = mongoose.model("ShoppingBasket", shoppingBasketSchema);
module.exports = { ShoppingBasket };
일단 Mongoose(몽구스) 스키마 모델에 아래 문장을 작성해야지 User Collection에 있는 documents ObjdectId를 참조하여 저장하도록 세팅이 된다.
type: Schema.Types.ObjectId,
ref: "User",
그런 후 api 요청할때 Json 내부에 writer의 값으로 User 모델의 ObjectId값을 전달해 준다.(ObjectId는 _id로 표기된다.)
const shoppingBasketData = {
writer: video.writer._id,
userFrom,
title: video.title,
description: video.description,
duration: video.duration,
thumbnail: video.thumbnail,
genre: video.genre,
filePath: video.filePath,
cost: video.cost,
};
const handleShoppingBasket = () => {
axios
.post("/api/shoppingBasket/addShoppingBasket", shoppingBasketData)
.then((response) => {
console.log(response);
if (response.data.success) {
alert("장바구니에 담았습니다.");
} else {
if (response.data.err.keyPattern.filePath) {
return alert("이미 장바구니에 담겼습니다.");
}
alert("오류가 발생했습니다. 나중에 시도해주세요.");
}
});
};
그 후 전달받은 내용을 저장한다. (save 부분)
const express = require("express");
const router = express.Router();
const { ShoppingBasket } = require("../models/ShoppingBasket");
router.post("/addShoppingBasket", (req, res) => {
// 장바구니 목록에 추가
const shoppingBasket = new ShoppingBasket(req.body);
console.log(req.body);
shoppingBasket.save((err, shoppingBasket) => {
if (err) return res.json({ success: false, err });
return res.status(200).json({
success: true,
});
});
});
router.post("/getShoppingBasketList", (req, res) => {
//로그인한 사용자 장바구니 목록
ShoppingBasket.find({ userFrom: req.body.loginUser })
.populate("writer")
.exec((err, shoppingbaskets) => {
if (err) return res.status(400).send(err);
res.status(200).json({ success: true, shoppingbaskets });
});
});
module.exports = router;
나중에 /getShoppingBasketList 로 ShoppingBasket Collection에서 목록을 가져올때 스키마 모델에서 작성했던, 참조하도록 했던 스키마 모델의 명칭을 populate 메서드의 인자로 주게되면 ShoppingBasket 목록을 가져오면서 참조된 User 모델도 같이 결과 값으로 받을 수 있다.
아래의 결과를 보면 리스트를 받아왔는데 해당 documents안에 Writer가 있을 수 있는 이유는 이전에 백엔드로 데이터를 전달할 때 writer에 ObjectId를 식별자로 전달했기 때문이다. 그래서 Video 모델에서 데이터를 가져오지만 User documents가 같이 출력되는것을 확인할 수 있다.
요약하면
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const shoppingBasketSchema = mongoose.Schema(
{
writer: {
type: Schema.Types.ObjectId,
ref: "User",
},
... 생략
위 코드에서 처럼 스키마 모델을 만들때 특정 모델의 documents의 ObejctId를 받을 수 있도록 작성하고, 데이터를 저장한 뒤에 몽구스의 populate를 사용하여 스키마 모델에 ObjectId 로 참조되어있는 Documents를 같이 호출할 수 있게 된다.
댓글
댓글 쓰기