본문 바로가기

db/NoSQL

[Mongo DB] 도규먼트 CRUD

들어가면서

몽고 DB에서 CRUD 하는 방식에 대해서 알아보자. 공부한 책의 예제를 기반으로 작성했기 때문에 movies 컬렉션에서 데이터를 다루는 방식으로 소개하겠습니다.

Create

단건 삽입

insertOne 메서드를 이용해서 문서를 만들 수 있습니다. 이때 생성된 문서는 _id 기본키가 추가되어 저장됩니다.

db.movies.insertOne( { "title" : "Stand by Me"} )

일괄 삽입

많은 수의 문서를 한 번에 전송하면 삽입 속도가 빨라집니다. 한 번에 일괄 삽입할 수 있는 데이터의 크기에는 제한이 있어서 초과되는 데이터는 여러개의 일괄 삽입 요청으로 분할되어 처리됩니다.

db.movies.insertMany( [ 
{ "title" : "Stand by Me"}, 
{ "title" : "war"}, 
{ "title" : "shark2"}
] )

일괄 삽입의 경우에는 삽입 순서는 입력한 데이터의 순서를 따릅니다. 이것은 정렬된 삽입입니다. 정렬된 삽입 처리중에 오류가 발생하면 이후 삽입 대기 중인 데이터는 삽입이 되지 않습니다.

정렬되지 않은 일괄 삽입

성능을 개선하기위해서 일괄 삽입시 옵션을 주어 삽입의 순서를 몽고 DB가 결정하도록 할 수 있습니다.

db.movies.insertMany( [ 
{ "title" : "Stand by Me"}, 
{ "title" : "war"}, 
{ "title" : "shark2"}
] , { "ordered" : false })

위의 예시 처럼 옵션 도큐먼트의 ordered 키를 false로 지정하면 정렬되지 않은 일괄 삽입을 사용할 수 있습니다. 정렬되지 않은 일괄 삽입 처리중 오류가 발생하면 삽입 오류가 발생한 문서를 제외한 다른 문서는 오류가 다시 발생하지 않는 이상 삽입이 정상적으로 처리가 됩니다.

READ

find 함수를 이용해서 몽고 DB의 데이터를 조회할 수 있습니다.
단건 조회시에는 findOne 함수를 통해서 데이터를 조회할 수 있습니다.

db.collectionName.find()
db.collectionName.findOne()

조건 필터링하는 법

몽고 DB에서는 json 형태로 조회할 데이터의 필터링할 수 있습니다. 이 과정은 SQL의 where문과 유사한 방식입니다.

완전 일치 조건 사용
db.users.find( { "username": "joe", "age" : 27 }

위의 예제에서는 유저이름이 joe이고 나이가 27인 사람을 조회하는 예시입니다. 입력한 데이터 조건은 And로 묶여서 처리가 됩니다.

비교 연산 조건 사용

몽고 DB에서 비교 연산을 위한 연산자를 제공합니다. 일반적으로 쓰이는 >, <, =을 사용하지 않고 $lt, $lte, $gt, $gte를 사용해서 비교 조건을 작성합니다.

db.users.find( {  "age" : { "$gte" : 18, "$lte" : 30 } } )

위의 예시처럼 조건을 사용할 속성에 json 형태의 문서를 입력하여 조건을 만들 수 있습니다. 예시에서 사용된 조건은 18이상 30이하인 나이인 사용자를 조회하는 예시입니다.

OR 조건 사용

특정 조건을 or를 통해서 조회할 때는 $or 연산자를 사용합니다.

db.raffle.find( {  "$or" : [ {"ticket_no" : 725}, {"winner" : true} ] } )

사용법은 예시 처럼 $or 속성을 사용하고 그 값으로 조건 배열을 정의해서 사용하면 됩니다.

in 조건 사용

가능하다면 $or이 아니라 $in을 사용하는 것이 좋습니다. $or 조건은 조회할 데이터를 크기를 줄이는데 기여하지 못하는 반면에 $in을 사용하면 조회할 데이터의 크기를 줄여서 성능상 이득을 볼 수 있기 때문입니다.

db.raffle.find( { "ticket_no" : { "$in" : [725, 542, 390] }} )

위의 예시 처럼 $in 연산자에서 사용할 조건을 배열 형태로 입력하여 사용할 수 있습니다.
비슷하게 사용할 수 있는 $nin 연산자는 not in 처리를 도와주는 연산자로 조건과 일치하지 않은 문서(데이터)를 반환하도록 조건을 만들 수 있습니다.

not 조건 사용

$not 조건은 어떤 조건에서도 적용할 수 있습니다.

db.users.find( { "id_num" : { "$mod" : [5, 1] }} )

다음 조건에 $not을 적용하고 싶다면

db.users.find( { "id_num" : { "$not" :  { "$mod" : [5, 1] } } } )

이렇게 $not을 적용해서 조건을 넣어주면 됩니다.

배열 조건 필터링

all 연산

배열 타입의 속성에서 원하는 데이터가 존재하는지를 판단하고 싶다면 $all연산자를 사용할 수 있습니다. 자바의 contains와 비슷합니다.

db.food.find( { fruit : { $all : ["apple", "banana"] } } )

다음 예시는 과일의 종류가 사과와 바나나가 포함된 문서들을 조회하는 예시입니다.

size 연산

배열의 크기를 통한 조건을 만들 때 사용합니다.

db.food.find( { "fruit" : { "$size" : 3 } } )

비교 연산자와 조합해서 사용할 수 없습니다. 이런 경우에는 size 속성을 추가해서 배열의 크기를 추적하는 식으로 사용을 합니다.

slice 연산자

배열 속성의 데이터를 제한하여 조회하고 싶다면 $slice연산자를 사용할 수 있습니다.

먼저 달린 댓글 10개 반환 예시

db.blog.posts.findOne(criteria, { "comments" : { "$Slice" : 10 } } )

나중에 달린 댓글 10개 반환 예시

db.blog.posts.findOne(criteria, { "comments" : { "$Slice" : -10 } } )

지정한 범위의 댓글 반환 예시 : 처음 23개를 건너뛰고 10개의 요소 반환하기

db.blog.posts.findOne(criteria, { "comments" : { "$Slice" : [23, 10] } } )

UPDATE

갱신 과정은 원자적으로 이루어집니다.

갱신 연산자

inc 제한자

특정 속성의 값을 증가시키고 싶을 때, 사용하는 연산자입니다.

db.analytics.updateOne( { "url" : "www.example.com"}, { "$inc" : { "pageviews" : 1} })

url이 일치하는 문서에서 페이지 뷰의 수를 1만큼 증가시키는 수정 로직을 다음 예시 처럼 작성하여 사용할 수 있습니다.

set 제한자

특정 속성의 값을 변경하고 싶다면 혹은 추가하고 싶다면 $set을 사용하여 값을 초기화해줄 수 있습니다.

db.users.updateOne({ "_id" : ObjectId("334dskfjalsdjflsad") },
                                    {"$set" : { "favorite book" : "War and Peace"} } )

반대로 특정 속성을 제거하고 싶다면 $unset연산자를 통해서 제거할 수 있습니다.

db.users.updateOne({ "_id" : ObjectId("334dskfjalsdjflsad") },
                                    {"$unset" : {"favorite book" : 1 } } )

배열 연산자

배열을 다루는데 갱신 연산자를 사용할 수 있습니다. 배열은 일반적으로 강력한 데이터 구조입니다. 연산자는 리스트에 대한 인덱스를 지정할 수 있습니다.

요소 추가하기

$push을 사용하여 배열의 요소를 추가할 수 있습니다.

comments 배열(속성)에 {...} 문서를 추가하는 예시

db.blog.posts.updateOne({"title" : "A blog post"},
                                            {"$push" :  { "comments : { ... } } } )
요소 제거하기

$pop을 사용하면 큐나 스택처럼 배열의 요소를 제거할 수 있습니다.
{ "$pop" : { "key" : 1 } }은 배열의 마지막 요소를 제거하는 표기이고 { "$pop" : { "key" : -1 } }은 배열의 처음 요소를 제거하는 표기입니다.


$pull은 주어진 조건에 맞는 배열 요소를 제거하는데 사용합니다. 조건에 맞는 데이터는 모두 제거되기 때문에 이를 주의해서 사용하는 것이 필요합니다.

db.lists.updateOne({}, { "$pull" : {"todo" : "laundry"} } )

단건 치환

replaceOne을 이용하면 하나의 문서의 내용을 교체할 수 있습니다. 스키마를 마이그레이션할 때 유용하게 사용할 수 있는 기능입니다. 이 기능을 사용할 때 주의할 점은 교체하는 문서가 오직 하나만 있어야 한다는 것 입니다. 하나가 아닌 여러개의 문서를 교체하고자 하면 갱신 요청이 실패하게 됩니다.

db.movies.replaceOne({ "_id " : ObjectId("4bd29dfddkjfdkjf1234dfd")}, { "name" :  "joe",  "age" : 20 } ) 

DELETE

단건 삭제

deleteOne을 사용하여 문서를 삭제할 수 있습니다. 이때 필터의 조건에 일치하는 문서가 여러개라면 처음으로 발견된 문서를 삭제하게 됩니다.

db.movies.deleteOne( { "_id" : 4 } )

일괄 삭제

조건에 부합하는 여러 문서를 삭제하기 위해서는 deleteMany를 사용하면 됩니다.

db.movies.deleteMany( { "year" : 1984 } )

컬랙션 삭제

전체 컬랙션을 삭제하고자 하면 drop을 사용하면 됩니다.

db.movies.drop()

Reference

몽고 DB 완벽 가이드

'db > NoSQL' 카테고리의 다른 글

2장 다양한 NoSQL 데이터 베이스  (1) 2023.10.23