The Web Developer - (Udemy)_ MongoDB

‍정진철·2022년 8월 6일
0

web devloper (udemy)

목록 보기
14/34

1) 데이터베이스 개요

What is MONGO?

  • According to Mongo's homepage, it is "the most popular database for modern applications". It is commonly used in combination with Node.

  • Mongo is a document database, which we can use to store and retrieve complex data form.

  • 정보를 저장해서 지속시켜야함. (데이터베이스의 기본)

Why use a Database? (Instead of just saving to a file?)

  • Databases can handle large amounts of data efficiently and store it compactly

  • They provide tools for easy insertion,querying,and updating of data.

  • They generally offer security features and control over access to data.

  • They (generally) scale well.

  • 데이터베이스는 일반적으로 어마어마한 데이터를 효율적으로 저장하고 압축하여 관리하기 쉽고 접속하기 쉽게 만들어 줌. (데이터 사이즈를 더 작게 압축)

  • 다양한 메소드와 언어로 된 수많은 도구와 레이어를 사용하면 데이터베이스 탑에서 데이터를 쉽게 삽입,문의,갱신,삭제 할 수 있음. (데이터 필터링 & 정렬 & 검색)

  • 데이터베이스의 탑에는 레이어가 하나 있는데 데이터 관리 시스템이라고 불리운다.
    이곳에서 보안기능이나 관리자로서의 접속을 누구에게 허용할지 제어하는 기능이 있음.

  • 파일에 저장했을 때 보다 관리측면에서 조정과 관리가 훨씬 쉬움.


2) SQL과 NoSQL 데이터베이스

SQL (MySQL, Postgres, SQLite, Oracle, MS SQL Server)

  • Structured Query Language database are relational databases.
    We pre-define a schema of tables before we insert anything.
  • 모든 일이 테이블에서 이루어짐.
  • 그래서 스키마와 테이블을 세팅한 후에야 데이터베이스에 다른것 추가 가능.
  • 모든게 패턴에 들어맞아야 함.

NoSQL Database (MongoDB, CouchDB, Neo4j)

  • NoSQL databases do not use SQL. There are many types of no-sql databases, including document, key-value and graph stores.
  • SQL의 구조화된 쿼리 언어를 쓰지 않고 많은 요소를 몽땅 포괄하는 방식.
  • 모든 카테고리를 한 곳에 집약시켜 놓은 상자 같음.
  • 그래서 유형도 다양.
  • 데이터를 여러 테이블로 나눌 필요가 X, 따라야 할 스키마와 패턴도 미리 정하지 X.
  • 대신 데이터를 있는 그대로 가져와 주어진 것에 대한 관련 정보를 데이터베이스의 한 인스턴스 안에 저장.
  • 훨씬 유연하고 자유로운 방식.
  • 객체나 데이터에 조각 안에 정보를 직접 끼워 넣을 수 있음.

3) MongoDB를 쓰는 이유

  • Mongo is very commonly, used with Node and Express(MEAN & MERN stacks).
  • Its easy to get started with.
  • It plays particularly well with JS
  • Its popularity also means there is a strong community of developers using Mongo.

4) MongoDB 설치

1) Homebrew 설치 - 모든 종류의 개발자 도구 설치를 도와주는 도구

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

2) brew tap mongodb/brew

3) brew install mongodb-community@6.0

4) brew services start mongodb-community@6.0

5) mongosh


5) Mongo Shell

show dbs

  • 데이터베이스 목록 보기

use (데이터베이스 이름)

  • 데이터베이스 만들기
  • 만든 후 show dbs 를 하면 animalShelter가 보이지 않는데 이유는 몽고는 실제로 데이터가 만들어질 때 까지는 '대기'상태로 존재.

Ctrl + c

  • 몽고 나가기

6) BSON 이란?

Mongo가 데이터베이스 안에서 기대하는 타입의 데이터

  • 이진법으로 데이터를 표현 (JSON의 이진법적 표현)
  • 훨씬 더 압축하여 저장 가능

출처: https://www.mongodb.com/json-and-bson


7) Mongo 데이터베이스에 삽입하기 (create)

삽입 할 때 에는 '집합'의 형식으로

  • 몽고의 좋은점은 아직 존재하지 않은 집합에 무언가를 삽입하면 집합이 만들어짐.
  • 집합을 사용하는 이유는 '조회'가 가능하기 때문.
  • 집합 입력시엔 javascript 객체
  • mongo에게 전달하면 BSON으로 변환

삽입 메소드 (insertOne, inserMany, insert)

- 'insert' 를 웬만하면 주로 사용


insertOne

  • db 조회 (db.(데이터베이스명).find()
  • _id: 기본키 (몽고에서 생성) - 고유값
  • 고유아이디는 작고,고유하며,값을 생성하는 것이 빠름.

insert

  • 집합에 대한 어떤 일관된 구조를 맞춰야 할 필요 X


  • 현재 db 위치를 바꾸면 이전에 만들었던 데이터베이스 조회 불가능

8) Mongo 데이터베이스에서 찾기 (find)

db.collection.find()


9) Mongo 데이터베이스 업데이트 하기 (Update)

{ $set : { field1: value1, ... }}

  • {name:Charlie}는 해당 객체를 찾기위한 기입임.
  • 이름이 찰리인 객체의 나이를 4 로 바꾼다 ($set)


  • 객체에 미리 지정되어 있지 않은 특성도 update 메소드로 추가시킬 수 있음.

  • 업데이트 타겟이 여러개 일 때 (updateMany)


  • 업데이트 시간 변경
  • lastChanged : 해당라인을 실행한 구체적 시기


10) Mongo 데이터베이스에서 삭제(Delete)

db.deleteOne, deleteMany


db.cats.deleteMany( { } ) -> 전부 삭제


11) 기타 Mongo 연산자

중첩되있을 때 데이터 찾기 (따옴표, 마침표)


$gt : (greater than) : '초과' 개념

  • 범위계산 시 유용 ( ~보다 많은 데이터 찾기)

$gte (greater than or equal) : '이상' 개념

  • $lt : (Less than) : '미만' 개념
  • $lte : (Less than or equal) : '이하' 개념

$in (해당 특징이 들어간 데이터 찾기)

  • 섞어서 연산자 적용 가능


$nin (해당 특징이 없는 데이터 찾기)


$or ( 두개의 조건 중 어느 것에 해당하는 데이터 찾기)


12) Moongoose 란?

O D M (Object Data Mapper or Object Document Mapper)

  • ODMs like Mongoose map documents coming from a database into usable Javascript objects.

  • Mongoose provides ways for us to model out our application data and define a schema. It offers easy ways to validate data and build complex queries from the comfort of JS.

  • Ex) Moongoose는 Mongo와 Node.js 를 연결해줌.

  • 몽구스는 Node와 Mongo DB를 이어주는 기본 드라이버 그 이상.

  • JS 측면에서 아주 유용한 여러 기능 제공.

  • Mongo에서 회신,삽입하려는 데이터를 매핑시켜 메서드를 추가할 수 있는 사용가능한 JS 객체로 만듬.

  • 또한 사전에 프리셋 스키마(Schema)를 정의 할 수 있으며 해당 데이터가 몽구스를 통해 레이아웃된 스키마를 따르도록 강제.

  • 즉, Mongo를 개선시켜 JS측면에서 보다 친숙하고 강력하게 만든것. (데이터나 문서를 JS 객체로 매핑)

  • 모든 툴은 기본적으로 데이터베이스를 번역해 사용하려는 프로그래밍 언어의 객체로 변환시켜 주는 것이다.


13) Mongo에 Mongoose 연결하기

const mongoose = require('mongoose');

//몽구스 mongoDB에 연결하기 // movieApp은 데이터베이스 폴더명
mongoose.connect('mongodb://localhost:27017/movieApp')
.then(() => {
    console.log("CONNECTION OPEN!")
}).catch(err => {
    console("ERROR!" , err) 
})

14) 우리의 첫 번째 Mongoose 모델

MODEL

  • 모델은 몽구스의 도움으로 생성되는 JS클래스로 몽고디비의 정보를 나타내며 구체적으로는 어떤 집합의 정보를 나타내는 것.
  • Ex) 몽구스의 도움을 받아 영화 모델을 만들 수 있는데 데이터베이스에서 작성한 영화 정보와 상호작용을 할 수 있는 다양한 메소드를 제공해줌.
  • 자바스크립트 클래스는 몽고디비에서 가져온 데이터로 모델을 만들고 상호작용을 도와 데이터베이스나 쿼리로 새로운 정보를 보내고 삭제/업데이트를 도와줌.

Schema (Mongo의 각기 다른 키 집합을 JS의 다른 타입으로 구조를 짜는 것)

  • 다양한 데이터 타입을 Mongo에서 가져오지만 해당 언어가 지원하는 데이터 타입이 있을 수도 있고 없을 수 도 있음.
  • 따라서 스키마를 정의함으로써 구체화시킴.


const movieSchema = new mongoose.Schema({
    title: String,
    year: Number,
    score: Number,
    rating: String
})

//Movie : 모델 이름 (단수형이면서 첫번째글자는 대문자로 작성해야함)
// mongoose는 Movie이름을 딴 'movies'라는 집합 생성 (자동으로 복수형이되고 첫글자 대문자로 만듦)
//집합이름: movies , 모델이름: Movie(타입은 클래스)
const Movie = mongoose.model('Movie', movieSchema)

  • 영화 인스턴스


데이터베이스에 실질적으로 저장하기

  • 데이터베이스에 저장 된 걸 알 수 있음.

15) 대량 삽입하기

insertMany( )

  • MongDB에서 온 원본 결과를 다루거나 유효성 검사를 통과한 문서인 Promise를 반환합니다.

  • 해당 메소드 사용할 땐 save 하지 않아도 됨.

  • 모델의 '단일' 인스턴스를 생성할 경우에는 save 호출해서 데이터 베이스에 저장시켜야함.

  • 하지만 insertMany를 호출하면 기본적으로 MongoDB에 바로 연결되어 한 번에 많이 입력할 수 있음.


16) Mongoose로 찾기

Movie.find({})

  • 쿼리 객체 반환 (thenable 객체)
  • 쿼리 객체는 내가 원하는 데이터를 바로 주지 않음.


findById( )


17) Mongoose로 업데이트하기

updateOne

  • 결과값을 반환시키지는 않음.


updateMany( )

  • 결과값을 반환시키지는 않음.


findOneAndUpdate( )

  • 결과를 반환해줌.
  • 다만 새롭게 변환된 결과값을 받고 싶으면 옵션을 세번째 인수에 지정 해줘야함.

  • {new:true} 라고 지정해주면 변환된 값이 출력됨
    (디폴트값이 false이므로 true라고 지정 필요).


18) Mongoose로 삭제하기

remove()

  • 돌려받는 값은 삭제된 '개수'뿐


deleteMany()

![](https://velog.velcdn.com/images/bik1111/post/40c1013f-bd90- 46d4-ac42-1fa4f3b7ec3e/image.png)


findOneAndDelete ()

  • update처럼 단순 update,delete시 아무데이터 반환 X (몇개가 수정되었는지만 알려줌)
    but,
  • findOneAndDelete, findOneAndUpdate, findByIdAndUpdate, findByIdAndDelete 등의 메소드는 해당 문서가 반환됨.

19) Mongoose 스키마 유효성 검사

required : true;

const mongoose = require('mongoose');

//몽구스 mongoDB에 연결하기 // shopApp은 데이터베이스 폴더명
mongoose.connect('mongodb://localhost:27017/shopApp')
.then(() => {
    console.log("CONNECTION OPEN!")
}).catch(err => {
    console("ERROR!" , err) 
})

const prodcutSchema = new mongoose.Schema({
    name : {
        type: String,
        required :true
    },
    price : {
        type: Number,
        required : true
    }

});

  • required : true는 해당 객체의 정보가 반드시 기입이 되어야 한다는 의미이다.
  • 따라서 bike라는 객체에 이름을 입력해주지 않자 오류가 발생.

20) 추가 스키마 제약 조건

Default

  • onSale 속성을 false 로 디폴트값 설정.

maxlength

	const bike = new Product ({name:'Bike Helmet form Hemlet makers', price: 599})

  • name 프로퍼티가 20글자 이상 되니 오류 발생.

array 적용

const prodcutSchema = new mongoose.Schema({
    name : {
        type: String,
        required :true,
        maxlength: 20
    },
    price : {
        type: Number,
        required : true,
        min : 0
    },
    onSale : {
        type:Boolean,
        default: false
    },
    categories : [String]

});

const Product = mongoose.model('Product', prodcutSchema);

const bike = new Product ({name:'Bike Helmet', price: 599, categories:['Cycling', 'Safety']})


중첩된 속성 넣기

	const prodcutSchema = new mongoose.Schema({
    name : {
        type: String,
        required :true,
        maxlength: 20
    },
    price : {
        type: Number,
        required : true,
        min : 0
    },
    onSale : {
        type:Boolean,
        default: false
    },
    categories : [String],
    qty: {
        online: {
            type: Number,
            default:0
        },
        inStore: {
            type:Number,
            default : 0
        }
    }

});
	~~~

![](https://velog.velcdn.com/images/bik1111/post/491e22cf-f62f-43b3-9969-cf9278e55bad/image.png)


---

# 21) Mongoose 업데이트 유효성 검사하기


- 데이터베이스를 작업하는 많은 프로그램들이 뭔가를 만들면 유효성 검사가 자동으로 적용되는데 일시적으로 한 번 검사하고 말아버림.
- 계속해서 내가 적용한 스키마의 기준에 충족이 되는지에 대한 적합성 여부를 지속적으로 하고 싶다면
runValidator: truen 라고 적용해야함

![](https://velog.velcdn.com/images/bik1111/post/9e65fdc4-b2b7-4769-bbd8-cfa27b868173/image.png)

---

# 22) Mongoose 유효성 검사 오류

> enum

![](https://velog.velcdn.com/images/bik1111/post/3b5ce5e5-cde5-4321-a437-006ebdfacae4/image.png)


![](https://velog.velcdn.com/images/bik1111/post/4e3ba0e0-cb99-48ae-835a-c476cd041ed5/image.png)

- enum: 선택지 안에서만 선택가능함 (S, M, L, XL) 의 선택지에서 XS를 선택해 오류발생.

---

# 23) 인스턴스 메소드

> 커스텀 메소드 스키마에 추가하기

- 정말 자주 쓰이며 Mongoose가 이미 제공하는 기능 외에 추가로 모델에 기능을 정의하거나 추가하는 방법.
- arrow(화살표)함수가 아닌 기존의 함수 표현식을 사용해야함 (중요) 화살표 함수는 함수에 대한 특정 값을 가질 수 없음.

> Product의 인스턴스 생성 _**(p)**_  - 방법1

![](https://velog.velcdn.com/images/bik1111/post/c1e71e42-b48a-4b9a-9e26-f3e2af5cb035/image.png)

> 모든 각각의 Product 객체에서 엑세스 할 수 있는 함수 (greet)

![](https://velog.velcdn.com/images/bik1111/post/8ed02b81-5520-49d2-9cda-61a1f7fef80a/image.png)

---

> 방법2

![](https://velog.velcdn.com/images/bik1111/post/22757138-b181-4ee0-bb2b-19448b6913c0/image.png)



![](https://velog.velcdn.com/images/bik1111/post/27ddb781-e447-46ab-9232-f878ec3468f0/image.png)

---

> this

const findProduct = async() => {
const foundProduct= await Product.findOne({ name : 'Bike Helmet' })
foundProduct.greet();
}


![](https://velog.velcdn.com/images/bik1111/post/9c45b6c6-073b-47ac-ab39-9376a8824df7/image.png)
![](https://velog.velcdn.com/images/bik1111/post/a16e19d6-405f-443d-b221-a4a4e07565b9/image.png)

---

> 특정 상품에 toggle 메소드 적용

- 첫번째 'foundProduct'는 toggle 함수_** 전 **_(true)
- await founProduct.toggleOnSale(); 수행 후 
- 두번째 'foundProduct'는 toggle 함수 _**후**_ (false)

![](https://velog.velcdn.com/images/bik1111/post/66485a9e-122d-4eb9-ad9b-cbd6c03251b8/image.png)


![](https://velog.velcdn.com/images/bik1111/post/da4e1fbd-ca06-46b5-8b74-23c4adf64360/image.png)

---

const Product = mongoose.model('Product', productSchema);

> 일반적으로 데이터를 조작하거나 모델에 포함된 정보와 직접 관련된 작업이라면 모델에 넣는다.

---

# 24) 정적 메소드 추가하기

> 인스턴스가 아닌 '모델' 자체에 적용되는 정적 메소드

- 정적메소드는 개별 인스턴스에서 작동되는게 X 
- 인스턴스 메소드는 this를 사용해 객체를 가르켰다면 정적 메소드는 this 자체적으로 해당 모델클래스를 가르킨다.

![](https://velog.velcdn.com/images/bik1111/post/d9fbb5eb-44ba-416c-bef7-0e01420be0c6/image.png)

![](https://velog.velcdn.com/images/bik1111/post/297aed58-b099-4f57-8885-89e208bd693e/image.png)


![](https://velog.velcdn.com/images/bik1111/post/7c817c3f-34c7-427d-8957-9aeca64e6c73/image.png)

![](https://velog.velcdn.com/images/bik1111/post/d70ac910-e28c-4f9c-a77d-f0a485798138/image.png)

- 가격이 모두 제로로 변했음.
- 클래스나 모델 자체에 커스텀하고 메소드 적용
- 다시말해 fireSale의 static 메소드는 특정한 모델 'Product'와 직접적으로 관련이 있는것이 아닌  전체의 Product 모델과 관련있는 것이다.
- 보통 모델의 정적메소드는 _**항목찾기,업데이트,생성, 삭제**_등의 업무를 볼 때 유용한 방식.
- Ex) Products.find, Products.update
- 따라서 정적메소드 안에서의 this는 어느 특별한 인스턴스를 가르키는 것이 아닌 모델 _**'전체'**_를 가르킴.


---


# 25) 가상 Mongoose

> 실제 데이터베이스 자체에는 존재하지 않는 스키마에 특성을 추가할 수 있게함.

- 포인트는 데이터베이스 내부에 존재하는 것이 아닌 JS의 Mongoose 에서만 가능.
- 일반적으로 접근하는 정보를 가질 때 사용.
- 기존 데이터에서 가져와서 데이터베이스에 저장 가능.


![](https://velog.velcdn.com/images/bik1111/post/4734ab90-b560-49dc-af92-4f4c965cefd8/image.png)

![](https://velog.velcdn.com/images/bik1111/post/f5e95d79-842f-43ef-a7d2-bf1b27a7948e/image.png)


----



profile
WILL is ALL

0개의 댓글