풀스택 맛보기7-MongoDB
MongoDB
- Json 형식과 같은 문서 기반(document-based) 데이터베이스. //일반적으로 sql based
사용법 (WSL 기준) sudo mongod --dbpath ~/data/db
다른 프롬프트 mongo 입력 후 실행
명령어
상태 확인
db 상태
show dbs
collection 상태
collection 확인 show collections
db 사용
use [DB 이름]
삭제
DB 삭제
use [DB 이름] db.dropDatabase()
collection 삭제
db.[삭제할 collection 이름].drop()
Mongoose
- node.JS와 MongoDB의 다리 역할을 하는 패키지.
🔧 npm install mongoose
src/db.js 생성 //server.js와 같은 폴더에 만들어줌
프롬프트창에 mongo 입력 후 상단에 있는 주소를 가져와서 적용.
DB 연결
- DB 연결 위치 설정 /src/db.js ```js import mongoose from “mongoose”;
mongoose.connect(“mongodb://127.0.0.1:27017/[사용할 DB명]”);
2. 서버에 db.js파일 import
src/server.js
```js
import "./db.js";
- 연결 여부와 에러를 메시지로 받기 /src/db.js ```js import mongoose from “mongoose”;
mongoose.connect(“mongodb://127.0.0.1:27017/agora”);
const db = mongoose.connection;
const handleOpen = () => console.log(“💡 Connected to DB 🔗”); const handleError = (error) => console.log(“DB Error”, error);
db.on(“error”, handleError); db.once(“open”, handleOpen);
💡once : 한번만 실행
### Model
- MongoDB에서 문서를 만들고 읽는다.
- Schema 정의에서 컴파일된 생성자이다.
src/models/Post.js 폴더와 파일 생성
#### Schema
- 데이터 형식을 지정한다.
src/models/Post.js
방식 1. 기본
```js
import mongoose, { mongo } from "mongoose";
const postSchema = new mongoose.Schema({
title: String,
content: String,
createdAt: Date,
hashtags: [{ type: String }],
meta: {
views: Number,
likes: Number,
},
});
const Post = mongoose.model("Post", postSchema);
export default Post;
방식 2. Type 추가
const postSchema = new mongoose.Schema({
title: { type: String, required: true },
content: { type: String, required: true },
createdAt: { type: Date, required: true, default: Date.now },
hashtags: [{ type: String }],
meta: {
views: { type: Number, default: 0, required: true },
likes: { type: Number, default: 0, required: true },
},
});
/src/server.js
import "./db.js";
import "./models/Post.js";
=> Post.js를 import 시키므로 show dbs를 통해 연결된 것을 확인할 수 있다.
=> db를 mongoose와 연결시켜서 post model을 인식시킨다.
SchemaTypes
trim
“He ll o !”.trim() => “Hello!”
사용 예시.
hashtags: [{ type: String, trim: true }]
Length
- 문자열의 최대/최소 길이
minLength & maxLength
title: { type: String, required: true, minLength: 1, maxLength: 30 },
Mongoose Query
Model.exists({})
- 필터에 따라 존재여부를 알 수 있다.
예시.
Model.exists({title: "hello"})
Model.exists({_id: [id]})
=> 존재여부에 따라 값 혹은 Null이 나온다.
Model.find()
const posts = await Post.find({}).sort({ createdAt: "desc" });
=> argument에 따라 오름차순, 내림차순 설정 가능
Model.findById()
- 해당 id를 검색하고 정보를 가져온다.
예시. 해당 id를 가지고 있는 post 가져오기
const { id } = req.params;
const post = await Post.findById(id);
Model.create()
Model.findByIdAndUpdate()
Model.findOneAndUpdate()
Model.findByIdAndDelete()
예시. 게시물 삭제
export const deletePost = async (req, res) => {
const { id } = req.params;
await Post.findByIdAndDelete(id);
return res.redirect("/");
};
💡 findByIdAndDelete(id) === findByIdAndDelete({_id:id})
Mongoos Middleware
postSchema.pre("save", async function () {
console.log("We are about to save: ", this);
});
console.log 결과 =>
We are about to save: {
title: 'abc',
content: 'abcde',
hashtags: [ '#aa', '#bb', '#cc' ],
meta: { views: 0, likes: 0 },
_id: new ObjectId("630c01ab5071f4572543f50d"),
createdAt: 2022-08-29T00:00:43.087Z
}
Call back 함수
function 속의 function
export const home = (req, res) => {
console.log("Start");
Post.find({}, (error, posts) => {
console.log(posts);
console.log("Hello");
});
console.log("Finish");
return res.render("home", { pageTitle: "Ἀγορά", fakeUser: fakeUser, posts: [] });
};
=> find가 오래 걸린다면 순서가 꼬일 수 있다.
💡두번째 줄 {}은 모든 것을 의미한다.
⭐ 출력 순서(find가 오래걸린 경우) ⭐
Start
Finish
Hello
[]
=> Callback 함수의 특성에 따라 “Finish” 전에 “Hello”가 먼저 나온다.
Promise
async & await
- await이 있다면 JS는 결과값을 받을 때까지 계속 기다려준다.
export const home = async (req, res) => {
console.log("Start");
const posts = await Post.find({});
console.log(posts);
console.log("Hello");
console.log("Finish");
return res.render("home", { pageTitle: "Ἀγορά", fakeUser: fakeUser, posts: [] });
};
⭐ 출력 순서 ⭐
Start
[]
Hello
Finish
=> call back 함수보다 더 직관적이다.
try & catch
- try 부분을 실행하고 오류가 난다면 catch를 실행한다.
export const home = async (req, res) => {
try {
console.log("Start");
const posts = await Post.find({});
console.log(posts);
console.log("Finish");
return res.render("home", { pageTitle: "Ἀγορά", fakeUser: fakeUser, posts: [] });
} catch {
return res.render("Error");
}
};
DB에 저장하기
JS Object를 만들기
해당 Object를 저장 src/controllers/postController.js 방법 1. new, object, save
export const postUpload = async (req, res) => { const { title, content, hashtags } = req.body; const post = new Post({ title: title, content: content, createdAt: Date.now(), hashtags: hashtags.split(",").map((word) => `#${word}`), meta: { views: 0, likes: 0, }, }); await post.save(); return res.redirect("/"); };=> 직접 save를 해줘야 한다.
방법 2. create
export const postUpload = async (req, res) => {
const { title, content, hashtags } = req.body;
await Post.create({
title: title,
content: content,
createdAt: Date.now(),
hashtags: hashtags.split(",").map((word) => `#${word}`),
meta: {
views: 0,
likes: 0,
},
});
return res.redirect("/");
};
=> 따로 save할 필요가 없다.