Mongo shell에서 직접 데이터베이스를 관리해야 하는 상황도 있지만, shell만 이용하는 것은 불편하다. 그래서 대부분의 경우 어플리케이션과 데이터베이스를 연결하는 툴(driver)을 사용하는데, Mongoose도 이런 툴 중 하나이다.
ODM
ODM(Object Data/Document Mapper)은 NoSQL 기반 데이터베이스에 저장되어있는 데이터를 유용한 객체 데이터로 변환해 주는 툴을 말한다. Mongoose도 수많은 ODM 중 하나로, Mongo에 저장되어 있는 데이터를 JS객체로 변환하고, JS 코드로 데이터베이스를 관리할 수 있게 만든다. ODM은 다음과 같은 역할을 한다.
- 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).
- 데이터를 객체 타입으로 변환하기 때문에, 데이터에 유용한 메서드를 추가할 수 있게 된다.
- DB에 추가되기 위해서 데이터가 따라야 할 shema(outline)를 정의할 수 있다.
- 복잡한 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));
- localhost:27017 | mongo에 기본으로 할당되는 port number
- movies | 사용할 데이터 베이스
- 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();
- new Schema()
- model(collection name, schema)
- 첫번째 인자는 대문자로 시작하는 단수형이어야 한다.
- Mongoose가 자동으로 소문자, 복수형으로 변환한다. => movies
- db에 movies라는 이름으로 collection이 생성된다.
- new collection | collection에 새로운 instance를 생성한다.
- 자동으로 id 프로퍼티가 추가된다.
- 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))
- find | 조건에 맞는 데이터를 모두 찾아 하나의 배열로 반환한다.
- 결과가 1개일 때에도 배열을 반환한다.
- findOne | 조건에 맞는 데이터를 하나만 찾아 객체로 반환한다.
- 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)
- updateOne
- updateMany
- title: { $in: [...] }에서 배열에 전달된 값 중 하나와 title이 완전히 일치해야 필터링된다.
- findOneAndUpdate | updateOne 함수와는 달리, 업데이트 할 데이터를 직접 반환하는데, 수정 내용이 반영되기 이전의 상태이다.
- 세번째 인자로 { new: true }를 전달하면 수정내용이 반영된 새로운 버전의 데이터를 반환한다.
Delete
Movie.delete({title: 'Amadeus'})
.then(msg => console.log(msg))
Movie.findByIdAndDelete('629d7190eeb472a7b92b4d73')
.then(data => console.log(data))
- delete | query 반환
- findByIdAndDelete | 객체 반환
'Study > Mongo & Mongoose' 카테고리의 다른 글
Schema (0) | 2022.06.08 |
---|---|
what is BSON? (0) | 2022.06.04 |
Mongo shell (0) | 2022.06.04 |