본문 바로가기

Study/Mongo & Mongoose

what is Mongoose?

Mongo shell에서 직접 데이터베이스를 관리해야 하는 상황도 있지만, shell만 이용하는 것은 불편하다. 그래서 대부분의 경우 어플리케이션과 데이터베이스를 연결하는 툴(driver)을 사용하는데, Mongoose도 이런 툴 중 하나이다. 

ODM

ODM(Object Data/Document Mapper)은 NoSQL 기반 데이터베이스에 저장되어있는 데이터를 유용한 객체 데이터로 변환해 주는 툴을 말한다. Mongoose도 수많은 ODM 중 하나로, Mongo에 저장되어 있는 데이터를 JS객체로 변환하고, JS 코드로 데이터베이스를 관리할 수 있게 만든다. ODM은 다음과 같은 역할을 한다. 

 

  1. DB에 저장되어 있는 데이터와, 삽입할 데이터를 mapping(연결)한다.
    • mapping | an operation that associates each element of a given set (the domain) with one or more elements of a second set (the range).
  2. 데이터를 객체 타입으로 변환하기 때문에, 데이터에 유용한 메서드를 추가할 수 있게 된다.
  3. DB에 추가되기 위해서 데이터가 따라야 할 shema(outline)를 정의할 수 있다. 
  4. 복잡한 quaries를 쉽게 사용할 수 있게 해 준다. 

 

+) ORM | Relation, SQL 기반 데이터 베이스와 어플리케이션을 연결할 때 사용되는 툴은 ORM이라고 부른다. 

How to start Mongoose?

connect 

mongoose 패키지를 설치하고, mongo를 실행한 상태에서 다음과 같은 코드를 작성하면 js로 mongo db에 접근하는 것이 가능하다.

 

const mongoose = require('mongoose');

mongoose
  .connect('mongodb://localhost:27017/movies', {
    useNewUrlParser: true,
    useUnifiedTopology: true,
  }) //
  .then(() => console.log('CONNECTION OPEN'))
  .catch((err) => console.log('ERROR!!!', err));

 

  1. localhost:27017 | mongo에 기본으로 할당되는 port number 
  2. movies | 사용할 데이터 베이스 
  3. connect method는 promise를 반환하므로 then과 catch를 chaining 할 수 있다. 

Schema & Model

Shema는 collection instance의 각 key가 어떤 데이터인지를 정의하며, 이를 이용해서 Model을 만든다. 이 때  Model은 collection의 정보를 나타내는 JS class이다. 

 

// 새로운 shema를 정의한다
const movieShema = new mongoose.Schema({
  title: String,
  year: Number,
  score: Number,
  rating: String,
});

// 새로운 model을 정의한다
// model의 첫번째 인자는 대문자로 시작하는 단수형이어야 한다
const Movie = mongoose.model('Movie', movieShema); 

// movies collection의 instance를 생성한다 
const amadeus = new Movie({
  title: 'Amadeus',
  year: 1986,
  score: 9.5,
  rating: 'R',
});

amadeus.save(); // amadeus를 DB에 저장한다 

amadeus.score = 9.2;
amadeus.save();

 

  1. new Schema() 
  2. model(collection name, schema) 
    • 첫번째 인자는 대문자로 시작하는 단수형이어야 한다. 
    • Mongoose가 자동으로 소문자, 복수형으로 변환한다. => movies
    • db에 movies라는 이름으로 collection이 생성된다. 
  3. new collection | collection에 새로운 instance를 생성한다. 
    • 자동으로 id 프로퍼티가 추가된다. 
  4. save | instance가 mondo DB에 추가된다. 

CRUD

insert many(Create)

Movie.insertMany([ {}, {}, {} ])
  .then(data => console.log(data))

 

  • promise를 반환한다. 
  • 컬렉션의 여러 개의 데이터를 한 번에 추가할 수 있다.
  • save를 호출하지 않고, 데이터 베이스에 바로 추가된다. 

find(Read)

find 함수는 query를 반환하는데, query는 promise가 아니라 theanable object(then을 사용할 수 있는 객체)이다. 이 때 query 객체 자체는 우리가 전달한 조건으로 필터링 된 데이터를 반환하지 않기 때문에 다음과 같이 사용한다. 

 

Movie.find({})
  .then(data => console.log(data))
  
Movie.find({ year: {$gte: 1995} })
  .then(data => console.log(data))
  
Movie.findById('629d7190eeb472a7b92b4d73')
  .then(data => console.log(data))

 

  1. find | 조건에 맞는 데이터를 모두 찾아 하나의 배열로 반환한다. 
    • 결과가 1개일 때에도 배열을 반환한다. 
  2. findOne | 조건에 맞는 데이터를 하나만 찾아 객체로 반환한다. 
  3. findById  
    • 특정 데이터에 대한 request를 다룰 때 url에 아이디가 포함되는 경우가 많은데, 이 때 유용하게 사용할 수 있다. 

Update 

update 함수는 query를 반환한다. 이 때 find 함수와 달리, then에 전달되는 데이터는 수정된 데이터가 아니라 수정 자체에 대한 정보(몇 개의 데이터가 수정되었는지 등)이다. 

 

Movie.updateOne({ name:'Amadeus' }, { year: 1984 })
  .then(data => console.log(data))
  
Movie.updateMany({title:{$in: ['Forrest Gump', 'Amadeus']}}, {score: 8.2})
  .then(console.log)
  
Movie.findOneAndUpdate({title:'Forrest Gump'}, {score: 7.5})
  .then(console.log)

 

  1. updateOne 
  2. updateMany
    • title: { $in: [...] }에서 배열에 전달된 값 중 하나와 title이 완전히 일치해야 필터링된다. 
  3. findOneAndUpdate | updateOne 함수와는 달리, 업데이트 데이터를 직접 반환하는데, 수정 내용이 반영되기 이전의 상태이다.  
    • 세번째 인자로 { new: true }를 전달하면 수정내용이 반영된 새로운 버전의 데이터를 반환한다. 

Delete

Movie.delete({title: 'Amadeus'})
  .then(msg => console.log(msg))

Movie.findByIdAndDelete('629d7190eeb472a7b92b4d73')
  .then(data => console.log(data))

 

  1. delete | query 반환
  2. findByIdAndDelete | 객체 반환

 

 

 

'Study > Mongo & Mongoose' 카테고리의 다른 글

Schema  (0) 2022.06.08
what is BSON?  (0) 2022.06.04
Mongo shell  (0) 2022.06.04