elice/WIL

[week_06] MongoDB์™€ Mongoose

๊ฑด๋ง๋”” 2022. 2. 16. 22:16

1. MongoDB

  • ๋Œ€ํ‘œ์ ์ธ NoSQL, Document DB
RDB NoSQL
- ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค (Relational DataBase)
- ์ž๋ฃŒ๋“ค์˜ ๊ด€๊ณ„๋ฅผ ์ฃผ์š”ํ•˜๊ฒŒ ๋‹ค๋ฃธ
- SQL ์งˆ์˜์–ด ์‚ฌ์šฉ โžก ๋ฐ์ดํ„ฐ ๊ตฌ์กฐํ™”
- ๊ตฌ์กฐํ™”๋œ ์งˆ์˜์–ด ์‚ฌ์šฉ X (Non SQL / Not Only SQL)
- ์ž๋ฃŒ ๊ฐ„์˜ ๊ด€๊ณ„์— ์ดˆ์  X
- ๋ฐ์ดํ„ฐ๋ฅผ ๊ตฌ์กฐํ™” X โžก ์œ ์—ฐํ•˜๊ฒŒ ๋ฐ์ดํ„ฐ ์ €์žฅ
  • DDL์ด๋‚˜ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐํ™” ๋“ฑ์˜ ์‚ฌ์ „์ž‘์—… ์—†์ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์‚ฌ์šฉ ๊ฐ€๋Šฅ
  • Database ํ•˜๋‚˜ ์ด์ƒ์˜ Collection์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ์ €์žฅ์†Œ
  • Collection ํ•˜๋‚˜ ์ด์ƒ์˜ Document๊ฐ€ ์ €์žฅ๋˜๋Š” ๊ณต๊ฐ„, SQL์˜ table๊ณผ ์œ ์‚ฌ
  • Document ์ €์žฅ๋˜๋Š” ์ž๋ฃŒ, SQL์˜ row์™€ ์œ ์‚ฌ
  • ObjectID document์˜ ์œ ์ผํ•œ ๊ธฐ ๊ฐ’, SQL์˜ primary key์™€ ์œ ์‚ฌ, ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋˜๋Š” ๋‚œ์ˆ˜ ๊ฐ’

 

2. Mongoose ODM

  • Object Data Modeling
  • MongoDB์— Collection์— ์ง‘์ค‘ํ•˜์—ฌ ๊ด€๋ฆฌํ•˜๋„๋ก ๋„์™€์ฃผ๋Š” ํŒจํ‚ค์ง€
  • Collection์„ ๋ชจ๋ธํ™”ํ•˜์—ฌ, ๊ด€๋ จ ๊ธฐ๋Šฅ๋“ค์„ ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค€๋‹ค.
โœจ Mongoose ODM ์‚ฌ์šฉ ์ˆœ์„œ
1. ์Šคํ‚ค๋งˆ ์ •์˜
2. ๋ชจ๋ธ ๋งŒ๋“ค๊ธฐ
3. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ
4. ๋ชจ๋ธ ์‚ฌ์šฉ

2-1. ์Šคํ‚ค๋งˆ ์ •์˜ํ•˜๊ธฐ

  • Collection์— ์ €์žฅ๋  Document์˜ ์Šคํ‚ค๋งˆ๋ฅผ Code-Level์—์„œ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ์Šคํ‚ค๋งˆ ์ž‘์„ฑ ๊ฐ€๋Šฅ
  • ๋‹ค์–‘ํ•œ ํ˜•์‹ ๋ฏธ๋ฆฌ ์ง€์ • ํ›„, ์ƒ์„ฑ/์ˆ˜์ • ์ž‘์—… ์‹œ ๋ฐ์ดํ„ฐ ํ˜•์‹ ์ฒดํฌ ๊ธฐ๋Šฅ ์ œ๊ณต
  • timestamps ์˜ต์…˜: ์ƒ์„ฑ/์ˆ˜์ • ์‹œ๊ฐ„ ์ž๋™ ๊ธฐ๋ก
const { Schema } = require('mongoose');

const PostSchema = new Schema({
	title: String,
    content: String,
}, {
	timestamps: true,
});

module.exports = PostSchema;

2-2. ๋ชจ๋ธ ๋งŒ๋“ค๊ธฐ

  • ์ž‘์„ฑ๋œ ์Šคํ‚ค๋งˆ๋ฅผ mongoose์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ชจ๋ธ๋กœ ๋ณ€ํ™˜
  • ๋ชจ๋ธ์˜ ์ด๋ฆ„์„ ์ง€์ •ํ•˜์—ฌ Populate ๋“ฑ์—์„œ ํ•ด๋‹น ์ด๋ฆ„์œผ๋กœ ๋ชจ๋ธ ํ˜ธ์ถœ ๊ฐ€๋Šฅ
const mongoose = require('mongoose')

const PostSchema = require('./schemas/board');

exports.Post = mongoose.model('Post', PostSchema);
// model ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉ => Post๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ PostSchema์™€ ํ•จ๊ป˜ ์ „๋‹ฌ
// Post๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ exports ํ•˜์—ฌ, model ๋ชจ๋“ˆ ์•ˆ์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

2-3. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐํ•˜๊ธฐ

  • connect ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์—ฐ๊ฒฐ
  • connect ํ•จ์ˆ˜ ์‚ฌ์šฉ ์‹œ, ์ž๋™์œผ๋กœ ์—ฐ๊ฒฐ์„ ๊ด€๋ฆฌ
  • ์ง์ ‘ ์—ฐ๊ฒฐ ์ƒํƒœ๋ฅผ ์ฒดํฌํ•˜์ง€ ์•Š์•„๋„ ๋ชจ๋ธ ์‚ฌ์šฉ ์‹œ ์—ฐ๊ฒฐ ์ƒํƒœ๋ฅผ ํ™•์ธํ•˜์—ฌ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•  ๋•Œ ์ž‘์—… ์‹คํ–‰
const mongoose = require('mongoose');

const { Post } = require('./models');

mongoose.connect('mongodb://localhost:27017/myapp');
// ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์—ฐ๊ฒฐ
// Post ๋ฐ”๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

2-4. ๋ชจ๋ธ ์‚ฌ์šฉํ•˜๊ธฐ

  • ์ž‘์„ฑ๋œ ๋ชจ๋ธ์„ ์ด์šฉํ•˜์—ฌ CRUD๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Œ
CRUD ํ•จ์ˆ˜๋ช…
CREATE create
READ find, findById, findOne
UPDATE updateOne, updateMany, findByIdAndUpdate, findOneAndUpdate
DELETE deleteOne, deleteMany, findByIdAndDelete, findOneAndDelete

1) CREATE

  • Document ์ƒ์„ฑ ํ›„ ๋ฐ˜ํ™˜
  • Document Object => ๋‹จ์ผ Document / Document Object์˜ Array => ๋ณต์ˆ˜ Document ์ƒ์„ฑ
const { Post } = require('./models');

async function main() {
	const created = await Post.create({
    	title: 'first title',
        content: 'second title',
    });
    
    const multipleCreated = await Post.create([
    	item1,
        item2
    ]);
}

2) FIND (READ)

  • Document๋ฅผ ๊ฒ€์ƒ‰
  • query๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒ€์ƒ‰ํ•˜๊ฑฐ๋‚˜, findById๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ObjectID๋กœ Documet ๊ฒ€์ƒ‰
    • { key : value }๋กœ exact match
    • $lt, $lte, $gt, $gte๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ range query ์ž‘์„ฑ
    • $in์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์ค‘ ๊ฐ’์œผ๋กœ ๊ฒ€์ƒ‰
    • $or๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์ค‘ ์กฐ๊ฑด ๊ฒ€์ƒ‰

3) UPDATE

  • Document๋ฅผ ์ˆ˜์ •
  • find~ ํ•จ์ˆ˜๋“ค์€ ๊ฒ€์ƒ‰๋œ Document๋ฅผ ์—…๋ฐ์ดํŠธ๊ฐ€ ๋ฐ˜์˜๋œ ๊ฐ’์œผ๋กœ ๋ฐ˜ํ™˜
  • ๊ธฐ๋ณธ์ ์œผ๋กœ $set operator๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ, Document๋ฅผ ํ†ต์งธ๋กœ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์Œ
    • ์žˆ๋Š” ์†์„ฑ์ด๋ผ๋ฉด ๋ณ€๊ฒฝํ•˜๊ณ , ์—†๋Š” ์†์„ฑ์ด๋ผ๋ฉด ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ˆ˜์ • ๊ธฐ๋Šฅ

4) DELETE

  • Document ์‚ญ์ œ
  • find~ ํ•จ์ˆ˜๋“ค์€ ๊ฒ€์ƒ‰๋œ Document๋ฅผ ๋ฐ˜ํ™˜

2-5. populate

  • RDB์˜ Join๊ณผ ์œ ์‚ฌํ•œ ๊ธฐ๋Šฅ
  • ์Šคํ‚ค๋งˆ๋ฅผ ์„ ์–ธํ•  ๋•Œ Document ์•ˆ์— Document๋ฅผ ๋‹ด์ง€ ์•Š๊ณ , ObjectID๋ฅผ ๊ฐ€์ง€๊ณ  referenceํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ• ์ œ๊ณต
  • Document์—๋Š” reference๋˜๋Š” ObjectID๋ฅผ ๋‹ด๊ณ , ์‚ฌ์šฉํ•  ๋•Œ populateํ•˜์—ฌ ํ•˜์œ„ Document์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์คŒ
const Post = new Schema({
	// Post๋ผ๋Š” ์Šคํ‚ค๋งˆ ์•ˆ์— user์™€ comment๊ฐ’์„ ๋‹ด์•„ ์„ ์–ธ
	...
    user: {
    	type: Schema.Types.ObjectId, // ObjectId ํƒ€์ž…
        ref: 'User' // ๋ชจ๋ธ ๋ ˆํผ๋Ÿฐ์Šค
    },
    comments: [{
    	type: Schema.Types.ObjectId,
        ref: 'Comment' // ๋ชจ๋ธ ๋ ˆํผ๋Ÿฐ์Šค
    }],
});

const post = await Post.find().populate(['user', 'comments']);
// find() ๋’ค์— populate => user์— ์„ ์–ธ๋œ user ์ด๋ฆ„ ๋“ฑ์„ post ๊ฐ์ฒด ๋‚ด์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

 

3. Express.js + Mongoose ODM

  • Express.js์˜ ์–ด๋А ๋ถ€๋ถ„์— Mongoose ODM์„ ์œ„์น˜์‹œํ‚ค๋ฉด ์ข‹์„์ง€ ์œ„์น˜ ๊ฒฐ์ • ์ค‘์š”
  • ์ผ๋ฐ˜์ ์œผ๋กœ models ๋””๋ ‰ํ„ฐ๋ฆฌ์— Schema์™€ Model์„ ๊ฐ™์ด ์œ„์น˜
  • app ๊ฐ์ฒด๋Š” ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹œ์ž‘์„ ์˜๋ฏธํ•˜๋Š” ๋ถ€๋ถ„์ด๋ฏ€๋กœ, ํ•ด๋‹น ๋ถ€๋ถ„์— DB ์—ฐ๊ฒฐ์„ ๋ช…์‹œํ•˜๋Š” mongoose.connect๋ฅผ ์œ„์น˜
  • ๋™์ž‘ ์ค‘์— ๋ฐœ์ƒํ•˜๋Š” DB ์—ฐ๊ฒฐ ๊ด€๋ จ ์ด๋ฒคํŠธ์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ ํ•„์š”

3-1. connection ๊ฐ์ฒด

mongoose.connect('----');

mongoose.connection.on('connected', () => {}); // ์—ฐ๊ฒฐ ์™„๋ฃŒ

mongoose.connection.on('disconnected', () => {}); // ์—ฐ๊ฒฐ ๋Š๊น€

mongoose.connection.on('reconnected', () => {}); // ์žฌ์—ฐ๊ฒฐ ์™„๋ฃŒ

mongoose.connection.on('reconnectFailed', () => {}); // ์žฌ์—ฐ๊ฒฐ ์‹œ๋„ ํšŸ์ˆ˜ ์ดˆ๊ณผ