๐ํค์๋: ๋ชฝ๊ณ ๋๋น, ์ปดํผ์ค, ๋ฐ์ดํฐ๋ฒ ์ด์ค, CRUD, ๋ชฝ๊ตฌ์ค
- mongoDB : ์๋ฐ์คํฌ๋ฆฝํธ ๋ฌธ๋ฒ ์ฌ์ฉ
- NoSQL vs SQL
mongoDB๋ NoSQL์ ๋ํ์ ์ธ ๋ฐ์ดํฐ๋ฒ ์ด์ค
NoSQL:
- ๊ณ ์ ๋ ํ ์ด๋ธ์ด ์๋ค. ์ปฌ๋ผ์ ๋ฐ๋ก ์ ์ํ์ง ์๊ณ ๊ทธ๋ฅ users ์ปฌ๋ ์ ์ ๋ง๋ค๊ณ ๋์ด๋ค. users์ปฌ๋ ์ ์๋ ์ด๋ ํ ๋ฐ์ดํฐ๋ ๋ค์ด๊ฐ ์ ์๋ค.
- JOIN ๊ธฐ๋ฅ์ด ์์ผ๋ฉฐ, ํ๋์ ์ฟผ๋ฆฌ๋ก ์ฌ๋ฌ ํ ์ด๋ธ์ ํฉ์น๋ ์์ ์ด ํญ์ ๊ฐ๋ฅํ์ง๋ ์๋ค. ๋์์ ์ฟผ๋ฆฌ๋ฅผ ์ํํ๋ ๊ฒฝ์ฐ ์ฟผ๋ฆฌ๊ฐ ์์ฌ ์์์น ๋ชปํ ๊ฒฐ๊ณผ๋ฅผ ๋ผ ๊ฐ๋ฅ์ฑ์ด ์๋ค.
→ But, ๋ชฝ๊ณ ๋๋น๋ ํ์ฅ์ฑ๊ณผ ๊ฐ์ฉ์ฑ ๋๋ฌธ์ ์ฌ์ฉํ๋ค.
→ ๋ฐ์ดํฐ์ ์ผ๊ด์ฑ์ ๋ณด์ฅํด์ฃผ๋ ๋์ ๋ฐ์ดํฐ๋ฅผ ๋น ๋ฅด๊ฒ ๋ฃ์ ์ ์๊ณ , ์ฝ๊ฒ ์ฌ๋ฌ ์๋ฒ์ ๋ฐ์ดํฐ๋ฅผ ๋ถ์ฐํ ์ ์๋ค.
Example) ํต์ฌ๊ธฐ๋ฅ ์ธ์ ๋น ๋ฐ์ดํฐ, ๋ฉ์์ง, ์ธ์ ๊ด๋ฆฌ ๋ฑ์๋ ํ์ฅ์ฑ๊ณผ ๊ฐ์ฉ์ฑ ์ํด ๋ชฝ๊ณ ๋๋น ์ฌ์ฉํ๋ค.
MySQL:
- users ํ ์ด๋ธ์ ๋ง๋ค ๋ name, age ๋ฑ์ ์ปฌ๋ผ๊ณผ ์๋ฃํ, ์ต์ ๋ฑ์ ์ ์ํ๋ค.
Example) ํญ๊ณต์ฌ ์์ฝ ์์คํ ์ ๊ฒฝ์ฐ ๋นํ๊ธฐ ํ์ ๊ดํ ์ ๋ณด๊ฐ ๋ชจ๋ ํญ๊ณต์ฌ์ ์ผ๊ด์ฑ ์๊ฒ ์ ๋ฌ๋์ด์ผํ๋ฏ๋ก ์ฃผ๋ก ์์ฝ ์ฒ๋ฆฌ ๋ถ๋ถ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฌ์ฉํ๋ค.
โป ์ด์์ฒด์ ์ ๋ฐ๋ผ ์ฑ ์ ์ฐธ๊ณ ํด ์ค์น
https://mongodb.com/try/download/community
์ด ์ฌ์ดํธ์ ๋ค์ด๊ฐ์ ๋ด๋ ค๋ฐ์ผ๋ฉด ๋๋ค.
- ๋ชฝ๊ณ ๋๋น๋ ๊ด๋ฆฌ ๋๊ตฌ๋ก ์ปดํผ์ค(compass)๋ฅผ ์ ๊ณต
https://mongodb.com/download-center/compass
์ด ์ฌ์ดํธ ๋ค์ด๊ฐ์ ๋ค์ด๋ฐ์ผ๋ฉด ๋๋ค.
- ์ปดํผ์ค๋ฅผ ์ฌ์ฉํ๋ฉด GUI๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฅผ ์๊ฐ์ ์ผ๋ก ๊ด๋ฆฌํ ์ ์์ด ํธ๋ฆฌํ๋ฏ๋ก ์ด์ฉํ๋ค.
๋ชฝ๊ณ ๋๋น ํ๋กฌํํธ์ ์ ์ํ ํ ์งํํ๋ค.
- ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๋ง๋๋ ๋ช ๋ น์ด๋ use [๋ฐ์ดํฐ๋ฒ ์ด์ค๋ช ] ์ด๋ค.
- ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ชฉ๋ก์ ํ์ธํ๋ ๋ช ๋ น์ด๋ show dbs ์ด๋ค.
5-1. CREATE(์์ฑ)
- ์ปฌ๋ ์ ์๋ ์๋ฌด ๋ฐ์ดํฐ๋ ๋ฃ์ ์ ์๋ค.
- ๋ชฝ๊ณ ๋๋น์ ์๋ฃํ:
์๋ฐ์คํฌ๋ฆฝํธ ๋ฌธ๋ฒ ์ฌ์ฉํ๋ค.
→ ์๋ฐ์คํฌ๋ฆฝํธ์ ์๋ฃํ์ ๋ฐ๋ฅธ๋ค. Date, Binary Data, ObjectId, Int, Long, Decimal, Timestamp, JavaScript ๋ฑ์ ์๋ฃํ์ด ์๋ค.
Undefined์ Symbol์ ๋ชฝ๊ณ ๋๋น์์ ์๋ฃํ์ผ๋ก ์ฌ์ฉํ์ง ์๋๋ค.
ObjectId๋ MySQL์์ ๊ธฐ๋ณธ ํค๋ก ์ฐ์ด๋ ๊ฐ๊ณผ ๋น์ทํ ์ญํ ์ ํ๋ค. -> ๊ณ ์ ํ ๊ฐ์ ๊ฐ์ง๋ฏ๋ก ๋คํ๋จผํธ๋ฅผ ์กฐํํ ๋ ์ฌ์ฉํ๋ค.
- db.์ปฌ๋ ์ ๋ช .insertOne(๋คํ๋จผํธ)๋ก ๋คํ๋จผํธ๋ฅผ ์์ฑํ ์ ์๋ค. ์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ์ฒด์ฒ๋ผ ์์ฑํ๋ค.
5-2. Read(์กฐํ)
- find({})๋ ์ปฌ๋ ์ ๋ด์ ๋ชจ๋ ๋คํ๋จผํธ๋ฅผ ์กฐํํ๋ค.
- ํน์ ํ๋๋ง ์กฐํํ๋ ๊ฒฝ์ฐ
nodejs> db.users.find({}, { _id: 0, name: 1, married: 1 });
[
{ "name" : "zero", "married" : false },
{ "name" : "nero", "married" : true }
]
- $gt : ์ํ๋ผ์ด์ฆ์ ์ฟผ๋ฆฌ์ด๋ค. ์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํด์ ๋ช ๋ น์ด ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ๋ค.
→ ๊ทธ ์ธ ๋ฉ์๋:
$gt(์ด๊ณผ), $gte(์ด์), $lt(๋ฏธ๋ง), $lte(์ดํ), $ne(๊ฐ์ง ์์), $or(๋๋), $in(๋ฐฐ์ด ์์ ์ค ํ๋), $or(OR์ฐ์ฐ), sort ๋ฉ์๋(์ ๋ ฌ, -1 ์ ๋ด๋ฆผ์ฐจ์, 1์ ์ค๋ฆ์ฐจ์), limit ๋ฉ์๋( ์กฐํํ ๋คํ๋จผํธ ๊ฐ์๋ฅผ ์ค์ ), skip ๋ฉ์๋( ๋คํ๋จผํธ ๊ฐ์๋ฅผ ์ค์ ํ๋ฉด์ ๋ช ๊ฐ๋ฅผ ๊ฑด๋๋ธ์ง ์ค์ )
5-3. Update(์์ )
nodejs> db.users.updateOne({ name: 'nero' }, { $set: { comment: '์๋
ํ์ธ์ ์ด ํ๋๋ฅผ ๋ฐ๊ฟ๋ณด๊ฒ ์ต๋๋ค!' } });
{
acknowledged: true,
insertedId: null,
matchedCount: 1,
modifiedCount: 0,
upsertedCount: 0
}
์ฒซ ๋ฒ์งธ ๊ฐ์ฒด๋ ์์ ํ ๋คํ๋จผํธ๋ฅผ ์ง์ ํ๋ ๊ฐ์ฒด์ด๊ณ , ๋ ๋ฒ์งธ ๊ฐ์ฒด๋ ์์ ํ ๋ด์ฉ์ ์ ๋ ฅํ๋ ๊ฐ์ฒด์ด๋ค. $set: ์ด๋ค ํ๋๋ฅผ ์์ ํ ์ง ์ ํ๋ ์ฐ์ฐ์์ด๋ค. ์ผ๋ถ ํ๋๋ง ์์ ํ๊ณ ์ถ์ ๋๋ ๋ฐ๋์ $set ์ฐ์ฐ์๋ฅผ ์ง์ ํ๋ค.
5-4. Delete(์ญ์ )
nodejs> db.users.deleteOne({ name: 'nero' })
{ acknowledged: true, deletedCount: 1 }
- ๋ชฝ๊ตฌ์ค๋ ์ํ๋ผ์ด์ฆ์ ๋ฌ๋ฆฌ ODM(Object Document Mapping)์ด๋ผ๊ณ ๋ถ๋ฆฐ๋ค. ๋คํ๋จผํธ๋ฅผ ์ฌ์ฉํ๋ฏ๋ก ODM์ด๋ค.
- ๋ชฝ๊ณ ๋๋น์ ์์ด์ ๋ถํธํ ๊ธฐ๋ฅ๋ค์ ๋ชฝ๊ตฌ์ค๊ฐ ๋ณด์ํ๋ค. -> ์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ์ฒด์ ๋งคํํ๋ ์ด์ ์ด๋ค.
- ๋ชฝ๊ตฌ์ค๋ ๋ชฝ๊ณ ๋๋น์ ๋ฐ์ดํฐ๋ฅผ ๋ฃ๊ธฐ ์ ์ ๋ ธ๋ ์๋ฒ ๋จ์์ ๋ฐ์ดํฐ๋ฅผ ํ ๋ฒ ํํฐ๋งํ๋ค.
- populate๋ผ๋ ๋ฉ์๋ : ๊ด๊ณ๊ฐ ์๋ ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ฒ ๊ฐ์ ธ์จ๋ค. ES2015 ํ๋ก๋ฏธ์ค ๋ฌธ๋ฒ๊ณผ ๊ฐ๋ ฅํ๊ณ ๊ฐ๋ ์ฑ์ด ๋์ ์ฟผ๋ฆฌ ๋น๋๋ฅผ ์ง์ํ๋ค.
6-1. ๋ชฝ๊ณ ๋๋น ์ฐ๊ฒฐํ๊ธฐ
๋ชฝ๊ณ ๋๋น๋ ์ฃผ์๋ฅผ ์ฌ์ฉํด ์ฐ๊ฒฐํ๋ค. ์ฃผ์ ํ์์ mongodb://[username:password@]host[:port][/[database][?options]]์ด๋ค. [ ] ๋ถ๋ถ์ ์์ด๋ ๋๊ณ ์์ด๋ ๋๋ค. username๊ณผ password์ ๋ชฝ๊ณ ๋๋น ๊ณ์ ์ด๋ฆ๊ณผ ๋น๋ฐ๋ฒํธ๋ฅผ ๋ฃ๋๋ค.
์ฃผ์ ์์:
mongodb://์ด๋ฆ:๋น๋ฐ๋ฒํธ@localhost:27017/admin
6-2. ์คํค๋ง ์ ์ํ๊ธฐ
const mongoose = require('mongoose');
const { Schema } = mongoose;
const userSchema = new Schema({
name: {
type: String,
required: true,
unique: true,
},
age: {
type: Number,
required: true,
},
married: {
type: Boolean,
required: true,
},
comment: String,
createdAt: {
type: Date,
default: Date.now,
},
});
module.exports = mongoose.model('User', userSchema);
- ๋ชฝ๊ตฌ์ค ๋ชจ๋์์ Schema ์์ฑ์๋ฅผ ์ฌ์ฉํด ์คํค๋ง๋ฅผ ๋ง๋ ๋ค. . ํ๋๋ฅผ ๊ฐ๊ฐ ์ ์ํ๋ ๋ฐฉ์์ผ๋ก ์ฌ์ฉํ๋ค.
- ๋ชฝ๊ตฌ์ค๋ ์์์ _id๋ฅผ ๊ธฐ๋ณธ ํค๋ก ์์ฑํ๋ฏ๋ก _id ํ๋๋ ์ ์ด์ค ํ์๊ฐ ์๊ณ , ๋๋จธ์ง ํ๋์ ์คํ๋ง ์ ๋ ฅํ๋ฉด ๋๋ค.
- name ํ๋์ ์๋ฃํ์ String์ด๊ณ ํ์์ด๋ฉฐ ๊ณ ์ ํ ๊ฐ์ดํ๊ณ , age ํ๋๋ Number ์๋ฃํ์ด๊ณ ํ์์ด๋ฉฐ, married ํ๋๋ ๋ถ ๊ฐ ์๋ฃํ์ด๊ณ ํ์์ด๋ค. comment ํ๋๋ String ์๋ฃํ์ด๊ณ , required๋ default ๋ฑ์ ์ต์ ์ด ํ์ํ์ง ์๋ค๋ฉด ๊ฐ๋จํ๊ฒ ์๋ฃํ๋ง ๋ช ์ํ๋ฉด ๋๋ค. createdAt ํ๋๋ Date ์๋ฃํ์ด๊ณ ๊ธฐ๋ณธ๊ฐ์ Date.now(๋ฐ์ดํฐ ์์ฑ ๋น์์ ์๊ฐ)์ด๋ค.
๋ง์ง๋ง์๋ ๋ชฝ๊ตฌ์ค์ model ๋ฉ์๋๋ก ์คํค๋ง์ ๋ชฝ๊ณ ๋๋น ์ปฌ๋ ์ ์ ์ฐ๊ฒฐํ๋ ๋ชจ๋ธ์ ๋ง๋ ๋ค.
6-3. ์ฟผ๋ฆฌ ์ํํ๊ธฐ
- GET /users์ POST /users ์ฃผ์๋ก ์์ฒญ์ด ๋ค์ด์ฌ ๋์ ๋ผ์ฐํฐ์ด๋ค. ๊ฐ๊ฐ ์ฌ์ฉ์๋ฅผ ์กฐํํ๋ ์์ฒญ๊ณผ ์ฌ์ฉ์๋ฅผ ๋ฑ๋กํ๋ ์์ฒญ์ ์ฒ๋ฆฌํ๋ค. GET /์์๋ ์ฌ์ฉ์ ๋ฐ์ดํฐ๋ฅผ ์กฐํํ์ง๋ง GET /users์์๋ ๋ฐ์ดํฐ๋ฅผ JSON ํ์์ผ๋ก ๋ฐํํ๋ค๋ ์ ์์ ์ฐจ์ด๊ฐ ์๋ค.
- ์ฌ์ฉ์๋ฅผ ๋ฑ๋กํ ๋๋ ๋จผ์ ๋ชจ๋ธ .create ๋ฉ์๋๋ก ์ ์ฅํ๋ค. ์ ์ํ ์คํค๋ง์ ๋ถํฉํ์ง ์๋ ๋ฐ์ดํฐ๋ฅผ ๋ฃ์์ ๋๋ ๋ชฝ๊ตฌ์ค๊ฐ ์๋ฌ๋ฅผ ๋ฐ์์ํค๊ณ , _id๋ ์๋์ผ๋ก ์์ฑ๋๋ค.
GET /users/:id/comments ๋ผ์ฐํฐ๋ ๋๊ธ ๋คํ๋จผํธ๋ฅผ ์กฐํํ๋ ๋ผ์ฐํฐ์ด๋ค. Comment ์คํค๋ง commenter ํ๋์ ref๊ฐ User๋ก ๋์ด ์์ผ๋ฏ๋ก, ์๋์ผ๋ก users ์ปฌ๋ ์ ์์ ์ฌ์ฉ์ ๋คํ๋จผํธ๋ฅผ ์ฐพ์ ํฉ์น๋ค. commenter ํ๋๊ฐ ์ฌ์ฉ์ ๋คํ๋จผํธ๋ก ์นํ๋๋ค. ์ด์ commenter ํ๋๋ ObjectId๊ฐ ์๋๋ผ ๊ทธ ObjectId๋ฅผ ๊ฐ์ง ์ฌ์ฉ์ ๋คํ๋จผํธ๊ฐ ๋๋ค.
const express = require('express');
const Comment = require('../schemas/comment');
const router = express.Router();
router.post('/', async (req, res, next) => {
try {
const comment = await Comment.create({
commenter: req.body.id,
comment: req.body.comment,
});
console.log(comment);
const result = await Comment.populate(comment, { path: 'commenter' });
res.status(201).json(result);
} catch (err) {
console.error(err);
next(err);
}
});
router.route('/:id')
.patch(async (req, res, next) => {
try {
const result = await Comment.update({
_id: req.params.id,
}, {
comment: req.body.comment,
});
res.json(result);
} catch (err) {
console.error(err);
next(err);
}
})
.delete(async (req, res, next) => {
try {
const result = await Comment.remove({ _id: req.params.id });
res.json(result);
} catch (err) {
console.error(err);
next(err);
}
});
module.exports = router;
์ฝ์
$ npm start
> learn-mongoose@0.0.1 start
> nodemon app
[nodemon] 2.0.16
[nodemon] to restart at any time, enter `rs`
[nodemon] watching: *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node app.js`
3002 ๋ฒ ํฌํธ์์ ๋๊ธฐ ์ค
๋ชฝ๊ณ ๋๋น ์ฐ๊ฒฐ ์ฑ๊ณต
Mongoose: users.createIndex({ name: 1 }, { unique: true, background: true })
→ ์๋ฒ ์คํ
Quiz
1. NoSQL์ ๋ํ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ( )๋ผ ํ๋ค.
2. ๋ชฝ๊ณ ๋๋น์์ ๊ด๋ฆฌํ๋ ๋๊ตฌ๋ ( )์ด๋ค.
3. ๋ชฝ๊ณ ๋๋น ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ํํ๋ ์์ฑ, ์กฐํ, ์์ , ์ญ์ 4๊ฐ์ง ์์ ์ ( )๋ผ๊ณ ํ๋ค.
4. ๋ชฝ๊ตฌ์ค๋ ์ํ๋ผ์ด์ฆ์ ๋ฌ๋ฆฌ ( )๋ผ๊ณ ๋ถ๋ฆฐ๋ค.
5. ๋ชฝ๊ณ ๋๋น์ ์์ด ๋ชฝ๊ตฌ์ค๊ฐ ๋ณด์ํ๋๋ฐ ์ด๋ ( )์ ๋งคํํ๋ ์ด์ ๋ค.
6. ๋ชฝ๊ณ ๋๋น๋ ( )๋ฅผ ์ฌ์ฉํด ์ฐ๊ฒฐํ๋ค.
7. ๋ชฝ๊ตฌ์ค๋ ( )๋ฅผ ๊ธฐ๋ณธํค๋ก ์ฌ์ฉํ๋ค.
8. Update ์ฝ๋์ด๋ค. ๋น์นธ์ ์ฑ์ฐ์์ค.
nodejs> ( ).( ).( )({ name: 'nero' }, { ( ): { comment: '์๋
ํ์ธ์ ์ด ํ๋๋ฅผ ๋ฐ๊ฟ๋ณด๊ฒ ์ต๋๋ค!' } });
{
acknowledged: true,
insertedId: null,
matchedCount: 1,
modifiedCount: 0,
upsertedCount: 0
}
9. name, married ์ด ๋ ๊ฐ์ ํน์ ํ๋๋ง ์กฐํํ๋ (READ) ์ฝ๋๋ฅผ ์์ฑํ์์ค.
1. ๋ชฝ๊ณ ๋๋น
2. ์ปดํผ์ค
3. CRUD
4. ODM
5. ์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ์ฒด
6. ์ฃผ์
7. _id
8.
nodejs> db.users.updateOne({ name: 'nero' }, { $set: { comment: '์๋
ํ์ธ์ ์ด ํ๋๋ฅผ ๋ฐ๊ฟ๋ณด๊ฒ ์ต๋๋ค!' } });
{
acknowledged: true,
insertedId: null,
matchedCount: 1,
modifiedCount: 0,
upsertedCount: 0
}
9.
nodejs> db.users.find({}, { _id: 0, name: 1, married: 1 });
[
{ "name" : "zero", "married" : false },
{ "name" : "nero", "married" : true }
]
์ถ์ฒ) ์กฐํ์ , ใNode.js ๊ต๊ณผ์ ๊ฐ์ 3ํใ, ๊ธธ๋ฒ(2022), 8์ฅ
Corner node.js 2ํ
Editor : Eunki
[๋ ธ๋ 2ํ] #8. MySQL (3) | 2024.11.29 |
---|---|
[๋ ธ๋ 2ํ] #7. ์ต์คํ๋ ์ค ์น ์๋ฒ ๋ง๋ค๊ธฐ (0) | 2024.11.22 |
[๋ ธ๋ 2ํ] #6. http ๋ชจ๋๋ก ์๋ฒ ๋ง๋ค๊ธฐ & ํจํค์ง ๋งค๋์ (1) | 2024.11.15 |
[๋ ธ๋ 2ํ] #5. ๋ ธ๋ ๊ธฐ๋ฅ(2) (0) | 2024.11.08 |
[๋ ธ๋ 2ํ] #4.๋ ธ๋ ๊ธฐ๋ฅ ์์๋ณด๊ธฐ(1) (0) | 2024.10.11 |