본문 바로가기

Etc/mongoDB

mongoDB 설치 및 CRUD Operation

Intro

이번 포스팅에서는 mongoDB를 docker를 통해 설치하고, mongo shell을 사용하여 몇가지 쿼리를 실행해보자. docker가 아닌 로컬에 설치하고 싶으면 docs.mongodb.com/guides/server/install/ 여기를 참조하자.

 

1. Install mongoDB

1-1. mongoDB 이미지 받아오기

아래 커맨드를 통해 dockerhub에서 mongoDB의 최신 이미지 파일을 다운받자.

docker pull mongo

1-2. mongoDB Container 생성

다운받은 이미지를 통해 mongoDB 컨테이너를 아래 명령어를 통해 생성하자

docker run --name mongodb -p 27017:27017 -v /Users/user/mongoTest/data/db:/data/db -d mongo

docker run option

  • --name : container의 이름을 설정하는 옵션
  • -p : host와 container의 port를 매핑하는 옵션, mongoDB는 디폴트로 27017번 port를 사용하기 때문에 host의 27017과 매핑
  • -v : host와 container volume 마운트, host의 /User/user~~ 경로과 container의 /data/db의 경로를 마운트한다. (/data/db 는 mongoDB가 데이터를 저장하는 공간)
  • -d : container를 detach모드로 실행, container가 터미널을 실행하지 않고, 백그라운드로 실행 된다.

1-3. mongodb Container 접속 후, mongo shell을 통해 mongoDB 접속

현재 mongodb Container는 detach모드로 실행중이다. 따라서 mongodb컨테이너의 터미널을 실행해서 container내부로 접속하여 내부에 설치된 mongoDB에 접속할 수 있다. 아래 명령어를 통해 mongod container에 접속하자

docker exec -i -t mongodb bash

 

성공적으로 mongodb container에 접속했다면, 이제 mongo shell을 사용하여 mongoDB에 접속! mongodb conatiner는 이미 mongoDB가 설치되어 있기 때문에, 간단하게 mongo 커맨드만 치면 mongo shell에 접속할 수 있다.

mongo

 

mongo shell에 정상적으로 접속했다면 아래와 같은 화면이 나옴!

 

2. Using mongo shell

1번과정을 무사히 마쳤다면 지금은 mongo shell에 접속하여 mongodb를 직접 조작할 수 있다. 지금부터 db및 collection, document를 생성하고 쿼리보는 연습을 해보자.

 

2-1. DB 생성

먼저 사용할 DB를 생성해야 하는데, RDBMS의 DB와 같은 개념이라고 생각하면 된다. use 명령어를 통해 사용할 DB를 선택할 수 있으며, 만약 DB가 존재하지 않는다면 새로 생성한다.

2-2. 현재 사용중인 DB 확인

db 명령어를 통해 현재 내가 사용하고 있는 DB가 무엇인지 확인할 수 있다. 좀전에 TestDataBase를 생성 및 사용했으니 TestDataBase라는 Output이 나오는걸 볼 수 있다.

2-3. DB 목록 확인

현재 어떤 DB들이 존재하는지 확인하기 위해서 show dbs 명령어를 통해 db목록을 확인할 수 있다.

 

3. mongoDB CRUD

이젠 내가 선택한 DB에 CRUD 명령어를 사용해서 데이터를 조작해보자.

3-1. Create Operation

Create Operation을 통해 새로운 document를 collection에 추가할 수 있다. 지금 DB만 생성하고, Collection은 생성하지 않았는데 Collection을 먼저 생성해야 하는게 아닌가? 라는 생각을 한다면, mongoDB는 스키마가 고정적으로 정해져 있지 않다. 따라서 하나의 Collection이 서로 다른 데이터 구조의 document를 가지는게 가능하며, document를 Collection에 추가할 때, Collection이 존재하지 않는다면 자동으로 Collection을 생성해준다.

 

MongoDB는 기본적으로 2가지 타입의 Create(insert) method를 제공한다.

  • db.<collection_name>.insertOne()
  • db.<collection_name>.insertMany()

MongoDB의 insert method는 단일 Collection에 대해서만 수행되며, 모든 write operation은 단일 document에 대해서 원자적이다.

Insert a Single Document

db.<collection_name>.insertOne()은 단일 collection에 단일 document를 insert하는 메서드이다.

다음 예제는 inventory라는 collection에 document를 insert하며, 만약 document가 _id 필드를 갖고 있지 않다면 mongoDB가 자체적으로 _id필드와 value값으로 ObjectID를 넣어준다.

db.inventory.insertOne(
   { item: "canvas", qty: 100, tags: ["cotton"], size: { h: 28, w: 35.5, uom: "cm" } }
)

 

Insert Multiple Document

db.<collection_name>.insertMany()는 단일 collection에 여러 document를 insert하는 메서드이다. document 배열을 인자로 받으며 생성된 document의 _id필드 배열을 리턴한다.

db.inventory.insertMany([
   { item: "journal", qty: 25, tags: ["blank", "red"], size: { h: 14, w: 21, uom: "cm" } },
   { item: "mat", qty: 85, tags: ["gray"], size: { h: 27.9, w: 35.5, uom: "cm" } },
   { item: "mousepad", qty: 25, tags: ["gel", "blue"], size: { h: 19, w: 22.85, uom: "cm" } }
])

 

3-2. Read Operation

Read operation은 collection의 document를 검색하는 메서드이다. MongoDB에서 기본적으로 아래 메서드를 제공하며, find() 메서드의 인자로 document를 식별할 수 있는 식별자를 인자로 제공하여, 이에 매치되는 document를 리턴한다.

  • db.<collection_name>.find()

select All Documents in a Collection

Collection에 존재하는 모든 document를 검색하려면, find()의 인자로 empty document를 전달하면 된다. 

db.<collection_name>.find({})

 

Specify Equality Condition

Collection의 document에 대해 field와 value에 매칭되는 document를 검색하기 위해서는, <field>:<value>와 같은 표현식을 find()의 인자로 전달한다.

db.<collection_name>.find({field: "value"})

 

Specify Conditions Using Query Operators

Query filter document라는 특수한 document를 사용해서, mongoDB의 쿼리에 조건을 추가할 수도 있다.

다음 예제는 inventory Collection에서, status가 A 또는 B인 document를 검색한다.

db.inventory.find( { status: { $in: [ "A", "D" ] } } )

// same Sql
SELECT * FROM inventory WHERE status in ("A", "D")

 

Specify AND conditions

find()메서드에 query filer(인자)를 추가하면, 각 쿼리를 논리적인 AND로 결합하여 복합 쿼리를 생성할 수 있다. 즉 쿼리는 모든 조건과 만족하는 document를 반환한다.

다음 예제는 inventory Collection에서 status가 A이고, qty가 30이하($lt)인 document를 반환한다.

db.inventory.find( { status: "A", qty: { $lt: 30 } } )

// same SQL
SELECT * FROM inventory WHERE status = "A" AND qty < 30

 

Specify OR conditions

$or 를 사용해면, 각 쿼리를 논리적인 OR로 결합하여 복합 쿼리를 생성할 수 있다. 즉 쿼리는 하나 이상의 조건과 일치하는 document를 반환한다.

다음 예제는 inventory Collection에서 status가 A이거나, qty가 30이하($lt)인 document를 반환한다.

db.inventory.find( { $or: [ { status: "A" }, { qty: { $lt: 30 } } ] } )

// same Sql
SELECT * FROM inventory WHERE status = "A" OR qty < 30

 

AND와 OR를 복합적으로 사용해보자. 다음 예제는 inventory Collection에서 status는 A이고, qty가 30이하 이거나, item이 p로 시작하는 document를 반환한다.

db.inventory.find( {
     status: "A",
     $or: [ { qty: { $lt: 30 } }, { item: /^p/ } ]
} )

// same Sql
SELECT * FROM inventory WHERE status = "A" AND ( qty < 30 OR item LIKE "p%")

 

간단한 Read Operator에 대해 알아보았는데, 실제로 mongoDB를 사용하기 위해, Embedded Documnt Query, Array Query 등 훨씬 더 많은 Read방법이 있으니 아래 링크에서 참조해보자.

Query Documents : docs.mongodb.com/manual/tutorial/query-documents/

3-3. Update Operation

Update Operation은 document를 수정하는 기능을 제공하며, mongoDB는 기본적으로 아래 메서드를 제공한다.

  • db.<collection_name>.updateOne(<filter>, <update>, <options>)
  • db.<collection_name>.updateMany(<filter>, <update>, <options>)
  • db.<collection_name>.replaceOne(<filter>, <update>, <options>)

Update method 도 insert method와 같이 단일 Collection에 대해 동작하며, 모든 Update method는 단일 document에 대해서 원자적이다. 

document를 update하기 위해, mongoDB는 update operator를 제공하고, update operator를 사용하기 위한 형식은 다음과 같다. $set과 같은 일부 Update operator는 만약 Update operator를 적용할 필드가 없는 경우 필드를 생성한다.

{
  <update operator>: { <field1>: <value1>, ... },
  <update operator>: { <field2>: <value2>, ... },
  ...
}

 

Update a single Document

db.<collection_name>.UpdateOne() 은 쿼리결과로 반환받은 document중 가장 첫번째 document를 Update한다.

다음 예제는 inventory Collection의 item이 "paper"인 document중 가장 첫번째 document를 Update한다.

db.inventory.updateOne(
   { item: "paper" },
   {
     $set: { "size.uom": "cm", status: "P" },
     $currentDate: { lastModified: true }
   }
)

 

위 예제에서 사용된 Update Operator를 살펴보자.

  • $set: Update할 document의 필드와 값을 지정한다. 위 예제는 size.uom필드의 값을 "cm"으로 status필드의 값을 "P"로 변경한다.
  • $currentDate: lastModified필드의 값을 현재 시간으로 변경한다.

 

Update multiple Document

다음 예제는 inventory Collection에서 qty가 50이하인 document들을 업데이트 하는 쿼리!

db.inventory.updateMany(
   { "qty": { $lt: 50 } },
   {
     $set: { "size.uom": "in", status: "P" },
     $currentDate: { lastModified: true }
   }
)

 

Replace a Document

document의 _id필드를 제외한 전체 내용을 변경하고 싶으면 db.<collection_name>.replaceOne()를 사용하면 된다. replaceOne()의 두번째 인자로 바꾸고 싶은 document를 전달하며, 전달하는 document는 반드시 field:value 쌍으로만 이루어져 있어야 한다. (update operator 같은게 포함되지 않은 완전한 단일 document 이어야 함)

 

새로운 document는 당연히 이전의 document와 다른 데이터 구조를 갖고있어도 되지만, _id필드는 포함하면 안된다! 왜냐하면 _id 필드는 immutable이기 때문이다. 만약 _id필드를 가지려면 이전 값과 동일한 값을 가져야 한다.

 

즉 Replace의 의미는 완전히 새로운 document로 대체하는 것이 아니라, document의 내용(_id를 제외한)을 Replace하는 것!

 

다음 예제는 item이 "paper"인 document중 첫번째 document를 두번째 인자에 정의된 document로 Replace한다.

db.inventory.replaceOne(
   { item: "paper" },
   { item: "paper", instock: [ { warehouse: "A", qty: 60 }, { warehouse: "B", qty: 40 } ] }
)

 

3-4. Delete Operation

Delete Operation은 Collection에서 document를 삭제하는 명령이며, mongo에서 기본적으로 다음 메서드를 제공한다.

  • db.<collection_name>.deleteOne()
  • db.<collection_name>.deleteMany()

 

deleteOne()은 하나만! Many()는 여러개 모두, 사용법은 다른 메서드처럼 Query Filter넣어주면 된다! 귀찮아서 이렇게 쓰는거 아님

 

 

Outro

mongoDB 공식 문서내용을 거의 번역만 한 수준의 포스팅이다. 개인적으로 mongoDB는 공식 문서가 잘 정리되어있는거 같으니 이 포스팅으로 감만 잡고 공식문서를 보는걸 추천한다!

 

mongoDB 공식 문서 : docs.mongodb.com/manual/

 

The MongoDB 4.4 Manual — MongoDB Manual

The MongoDB 4.4 Manual Welcome to the MongoDB 4.4 Manual! MongoDB is a document database designed for ease of development and scaling. The Manual introduces key concepts in MongoDB, presents the query language, and provides operational and administrative c

docs.mongodb.com

 

'Etc > mongoDB' 카테고리의 다른 글

mongo DB란?  (0) 2021.01.07