MongoDB & Mongoose

Yeonnยท2024๋…„ 10์›” 28์ผ
0

Backend ๐Ÿ‘€

๋ชฉ๋ก ๋ณด๊ธฐ
3/10
post-thumbnail

โ“DataBase

๐ŸŒฑ ์—ฌ๋Ÿฌ ์‚ฌ์šฉ์ž์™€ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์ด ๊ณต๋™์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ์ดํ„ฐ๋“ค์˜ ์ง‘ํ•ฉ

๐Ÿ“ DBMS( DataBase Management System )

  • DataBase๋ฅผ ํ†ตํ•ฉํ•˜์—ฌ ์ €์žฅํ•˜๊ณ  ์šด์˜ํ•˜๋Š” ์‹œ์Šคํ…œ

๐Ÿ“ DataBase ํ•„์š”์„ฑ

  • ํŒŒ์ผ ์ฒ˜๋ฆฌ์˜ ํ•œ๊ณ„
    • ๋ฐ์ดํ„ฐ ์ข…์†์˜ ๋ฌธ์ œ: ๋ฐ์ดํ„ฐ์˜ ๊ตฌ์กฐ๊ฐ€ ๋ฐ”๋€Œ๋ฉด ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์˜ ๊ตฌ์กฐ๋„ ๋ฐ”๋€Œ์–ด์•ผ ํ•จ
    • ๋ฐ์ดํ„ฐ ์ค‘๋ณต์˜ ๋ฌธ์ œ: ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ ๋ณ„๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ์ดํ„ฐ ์ค‘๋ณต์˜ ์œ„ํ—˜
    • ๋ฐ์ดํ„ฐ ๋ฌด๊ฒฐ์„ฑ์„ ์ง€ํ‚ฌ ์ˆ˜ ์—†์Œ

๐Ÿ“ย DataBase ํŠน์ง•

๐ŸŒฑ ์‹ค์‹œ๊ฐ„ ์ ‘๊ทผ์„ฑ, ์ง€์†์ ์ธ ๋ณ€ํ™”, ๋™์‹œ ๊ณต์œ , ๋‚ด์šฉ์— ๋Œ€ํ•œ ์ฐธ์กฐ

  • ์‹ค์‹œ๊ฐ„ ์ ‘๊ทผ์„ฑ: ์‚ฌ์šฉ์ž๊ฐ€ ์›ํ•  ๋•Œ ์–ธ์ œ๋“ ์ง€ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•ด์•ผ ํ•จ
  • ์ง€์†์ ์ธ ๋ณ€ํ™”: ๋ฐ์ดํ„ฐ์˜ ์‚ฝ์ž…, ์‚ญ์ œ, ๊ฐฑ์‹ ์„ ํ†ตํ•ด ์ตœ์‹  ๋ฐ์ดํ„ฐ๋ฅผ ์œ ์ง€ํ•ด์•ผ ํ•จ / CRUD
  • ๋™์‹œ ๊ณต์œ : ์—ฌ๋Ÿฌ ์‚ฌ์šฉ์ž๊ฐ€ ๋™์‹œ์— ์ด์šฉํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•จ
  • ๋‚ด์šฉ์— ๋Œ€ํ•œ ์ฐธ์กฐ: ๋ฐ์ดํ„ฐ๊ฐ€ ์ €์žฅ๋œ ๋ฌผ๋ฆฌ์  ์œ„์น˜๊ฐ€ ์•„๋‹Œ ๊ฐ’์„ ๊ฐ€์ง€๊ณ  ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•จ

๐Ÿ“ย Database/DBMS์˜ ์ข…๋ฅ˜

  • RDBMS( ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ด€๋ฆฌ ์‹œ์Šคํ…œ )
    • ํ…Œ์ด๋ธ”๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ํ‘œํ˜„( ํ–‰๊ณผ ์—ด๋กœ ๊ตฌ์„ฑ )
    • ๊ด€๊ณ„ ๋ชจ๋ธ ๊ธฐ๋ฐ˜
    • ๋ฌด๊ฒฐ์„ฑ๊ณผ ์•ˆ์ •์„ฑ์ด ์ค‘์š”ํ•œ ๊ฒฝ์šฐ ์‚ฌ์šฉ
    • MySQL, PostgreSQL, MariaDB ๋“ฑ
  • NoSQL
    • ํ‘œํ˜„ ๋ฐฉ์‹์ด ๊ณ ์ •์ ์ด์ง€ ์•Š์Œ
    • ๋Œ€์šฉ๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๋ฅผ RDB๋ณด๋‹ค ๋น ๋ฅด๊ฒŒ ์ฒ˜๋ฆฌ
    • ๊ตฌ์กฐ๊ฐ€ ์ผ๊ด€์ ์ด์ง€ ์•Š์€ ๋น…๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒฝ์šฐ ์‚ฌ์šฉ
    • MongoDB, Redis, Apache Cassandra ๋“ฑ

โ“ NoSQL

๐ŸŒฑ ์‚ฌ์ „์ž‘์—… ์—†์ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์‚ฌ์šฉ ๊ฐ€๋Šฅ
๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ž‘์—…์— ํฌ๊ฒŒ ๊ด€์—ฌํ•˜์ง€ ์•Š๊ณ  ํ”„๋กœ์ ํŠธ๋ฅผ ๋น ๋ฅด๊ฒŒ ์ง„ํ–‰ ๊ฐ€๋Šฅ

โ“ย MongoDB

๐ŸŒฑ
Document DB: ์ž๋ฃŒ๋ฅผ Document( ๋ฌธ์„œ )๋กœ ์ €์žฅ
Database > Collection > Document

  • DataBase
    • ํ•˜๋‚˜ ์ด์ƒ์˜ collection์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ๊ฐ€์žฅ ํฐ ๋‹จ์œ„์˜ ์ €์žฅ์†Œ
  • Collection
    • ํ•˜๋‚˜ ์ด์ƒ์˜ Document๊ฐ€ ์ €์žฅ๋˜๋Š” ๊ณต๊ฐ„
    • RDBMS์˜ table๊ณผ ์œ ์‚ฌํ•˜์ง€๋งŒ ์Šคํ‚ค๋งˆ๋ฅผ ์ •์˜ํ•˜์ง€ ์•Š์Œ
  • Document
    • ํ•˜๋‚˜์˜ ์ž๋ฃŒ
    • RDBMS์˜ row์™€ ์œ ์‚ฌํ•˜์ง€๋งŒ ๊ตฌ์กฐ์˜ ์ œ์•ฝ์ด ์—†์Œ
    • BSON ํ˜•์‹์œผ๋กœ ์ €์žฅ( JSON๊ณผ ์œ ์‚ฌ )
    • ๊ฐ Document ์•ˆ์—๋Š” ์œ ์ผํ•œ ํ‚ค ๊ฐ’์ด ๋˜๋Š” _id๊ฐ€ ์กด์žฌ
      • ์‹๋ณ„๊ฐ’( unique ), ์ค‘๋ณต๋˜์ง€ ์•Š์Œ
      • RDBMS์˜ primary key์™€ ์œ ์‚ฌ

โœ”๏ธย MongoDB ์„ค์น˜ํ•˜๊ธฐ

  • โœ… MongoDB MongoDB Community Server
    • ์„ค์น˜ ํ›„ ํ„ฐ๋ฏธ๋„์—์„œ mongod๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์„ค์น˜๋œ ๊ฒƒ !
    • mongosh: MongoDB ์ œ์–ด ๊ฐ€๋Šฅํ•œ ์‰˜์ด ์—ด๋ฆผ
      • ์ดํ›„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ง์ ‘ ํ™•์ธํ•  ๋•Œ ์‚ฌ์šฉ

โœ”๏ธย Mongoose

๐ŸŒฑ ๊ฐ€์žฅ ๋Œ€ํ‘œ์ ์ธ MongoDB ODM( object document mapping )

  • Mongoose์˜ ํŠน์ง•
    • ์—ฐ๊ฒฐ ๊ด€๋ฆฌ
      • ๊ฐ„๋‹จํ•˜๊ฒŒ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€์˜ ์—ฐ๊ฒฐ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌ
    • ์Šคํ‚ค๋งˆ ๊ด€๋ฆฌ
      • ์ฝ”๋“œ ์ž‘์„ฑ๊ณผ ํ”„๋กœ์ ํŠธ ๊ด€๋ฆฌ์— ์œ ์šฉ
      • ์ฝ”๋“œ ๋ ˆ๋ฒจ์—์„œ ์Šคํ‚ค๋งˆ๋ฅผ ์ •์˜ํ•˜๊ณ  ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์คŒ
    • Populate
      • MongoDB๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ Join์„ ์ œ๊ณตํ•˜์ง€ ์•Š์Œ โ†’ aggregate๋ผ๋Š” ๋ณต์žกํ•œ ์ฟผ๋ฆฌ ์ž‘์„ฑํ•ด์•ผ ํ•จ
      • populate๋ฅผ ํ†ตํ•ด aggregate ์ž‘์„ฑ ์—†์ด๋„ ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ตฌํ˜„ ๊ฐ€๋Šฅ

โœ”๏ธย Mongoose ์‚ฌ์šฉํ•˜๊ธฐ

๐ŸŒฑ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ โ†’ ์Šคํ‚ค๋งˆ ์ •์˜ โ†’ ๋ชจ๋ธ ์ƒ์„ฑ โ†’ ๋ชจ๋ธ ์‚ฌ์šฉ

  • ๋ฐ์ดํ„ฐ ์—ฐ๊ฒฐ
    • Mongoose ์„ค์น˜: npm i mongoose
    • src ๋‚ด๋ถ€์— db.js ์ƒ์„ฑ: DB ๊ด€๋ จ ์„ค์ •
    • index.js: ์—”ํŠธ๋ฆฌ ํฌ์ธํŠธ์— db.js import
      // db.js
      import mongoose from 'mongoose';
      
      mongoose.connect(`${MongoDB URL}${DB์˜ ์ด๋ฆ„}`);
      
      const database = mongoose.connection; // ํ˜„์žฌ DB ์—ฐ๊ฒฐ ์ƒํƒœ ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๋Š” ๊ฐ์ฒด
      
      // on ๋ฉ”์„œ๋“œ๋กœ ์—๋Ÿฌ ๋ฐœ์ƒ ์‹œ ์‹คํ–‰๋˜๋Š” ๋™์ž‘ ์ •์˜
      database.on('error', (err) => { 
      	console.log('Database Error!', err);
      });
      
      // once ๋ฉ”์„œ๋“œ๋กœ ์ตœ์ดˆ ์—ฐ๊ฒฐ ์‹œ ํ•œ ๋ฒˆ ์‹คํ–‰๋˜๋Š” ๋™์ž‘ ์ •์˜
      database.once('open', () => {
      	console.log('DB connected');
      });
  • ์Šคํ‚ค๋งˆ ์ •์˜
    • src > models ํด๋” ์ƒ์„ฑ
      • models ๋‚ด๋ถ€์— ์Šคํ‚ค๋งˆ ์ •์˜ํ•  js ํŒŒ์ผ ์ƒ์„ฑ
      • ์Šคํ‚ค๋งˆ ์ •์˜ํ•˜๊ธฐ
        // post.js
        
        import { Schema } from 'mongoose';
        
        const PostSchema = new Schema( // ์Šคํ‚ค๋งˆ ๊ฐ์ฒด ์ƒ์„ฑ
        	{
        		title: String,
        		content: String,
        		required: true,
        	},
        	{
        		timestamps: true
        	},
        );

โœ… Mongoose v8.7.1: SchemaTypes

  • ๋ชจ๋ธ ์ƒ์„ฑ
    • ์ž‘์„ฑํ•œ ์Šคํ‚ค๋งˆ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ชจ๋ธ ๊ฐ์ฒด ์ƒ์„ฑ
      // ์œ„์— ์ž‘์„ฑํ•œ post.js์— ์ด์–ด์„œ ์ž‘์„ฑ
      
      const Post = mongoose.model('Post', PostSchema); 
      // ์ž‘์„ฑํ•œ ์Šคํ‚ค๋งˆ ๊ธฐ๋ฐ˜ ๋ชจ๋ธ ๊ฐ์ฒด ์ƒ์„ฑ
      // ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜: ๋ชจ๋ธ์˜ ์ด๋ฆ„, ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ colliction์˜ ์ด๋ฆ„
      // ๋‘ ๋ฒˆ์งธ ์ธ์ˆ˜: ์Šคํ‚ค๋งˆ ๊ฐ์ฒด
      
      export default Post;
  • ๋ชจ๋ธ ์‚ฌ์šฉ
CRUD๋ชจ๋ธ ๊ฐ์ฒด์˜ ๋ฉ”์„œ๋“œ
Createcreate
Readfind, findeById, findOne
UpdateupdateOne, updateMany, findByIdAndUpdate, findOneAndUpdate
DeletedeleteOne ,deleteMany, findByIdAndDelete, findOneAndDelete
๊ธฐํƒ€save

โ“ย ๊ฐ„๋‹จํ•œ API ์ œ์ž‘ํ•˜๊ธฐ

  • DB ์—๋Ÿฌ๋Š” ์–ธ์ œ๋“ ์ง€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋ฐ˜๋“œ์‹œ tryโ€ฆcatch๋กœ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ !!
  • ๋ชจ๋ธ์˜ ๋ชจ๋“  ๋ฉ”์„œ๋“œ๋Š” Promise ๋ฐ˜ํ™˜ํ•˜๋ฏ€๋กœ ์‚ฌ์šฉ !

โœ”๏ธย Create

postsRouter.post('/', async (req, res) => {
	const { title, cocntent } =req.body;
	
	try{
		awiat Post.create({ title, content });
		res.send('Post Successfully Created');
	} catch (err) {
		res.status(500).send('Server Error');
	}
});

โœ”๏ธย Read

postsRouter.get('/', async (req, res) => {
	try{
		const allPosts = await Post.find({})
		res.json(allPosts);
	} catch (err) {
		res.status(500).send('Server Error');
	}
});
postsRouter.get('/:id', async (req, res) => {
	const { id } =req.params;

	try{
		const foundPost = await Post.findById(id);
		if(!foundPost) res.status(404).send('Post not found');
		else res.json(foundPosts);
	} catch (err) {
		res.status(500).send('Server Error');
		return;
	}
});

โœ”๏ธย Update

postsRouter.put('/:id', async (req, res) => {
	const { id } =req.params;
	const { title, cocntent } =req.body;

	try{
		const foundPost = await Post.findByIdAndUpdate(id, {
			title,
			content,
		});
		if(!foundPost) res.status(404).send('Post not found');
		else res.json(foundPosts);
	} catch (err) {
		res.status(500).send('Server Error');
	}
});

โœ”๏ธย Delete

postsRouter.put('/:id', async (req, res) => {
	const { id } =req.params;

	try{
		const foundPost = await Post.findByIdAndDelete(id);
		if(!foundPost) res.status(404).send('Post not found');
		else res.json(foundPosts);
	} catch (err) {
		res.status(500).send('Server Error');
	}
});

0๊ฐœ์˜ ๋Œ“๊ธ€