Notepad

업데이트, 원자적 연산, 삭제

1. 도큐먼트 업데이트

  • MongoDB의 도큐먼트 업데이트 방법
    • 도큐먼트 전체 대치
    • 업데이트 연산자를 이용하여 도큐먼트 특정 필드 수정

1.1 대치에 의한 수정

user_id = ObjectId("4c4b1476238d3b4dd5003981");
doc = db.users.findOne({_id: user_id});     // 1.도큐먼트 조회
doc['email'] = 'mongodb-user@mongodb.com';  // 2.조회한 도큐먼트에 대한 수정
db.users.update({_id: user_id}, doc);       // 3.수정한 도큐먼트로 대치
  • 여러 사용자가 동일한 도큐먼트를 업데이트하는 경우 마지막으로 쓰기 연산이 수행된 내용이 저장

1.2 연산자에 의한 수정

user_id = ObjectId("4c4b1476238d3b4dd5000001")
db.users.update({_id: user_id},
    {$set: {email: 'mongodb-user2@mongodb.com'}} // $set 연산자를 이용하여 email 변경
)
  • $set 연산자를 사용하여 필드를 주어진 값으로 설정

1.3 비교

  • 대치 방식 장점
    • 복잡한 모델링 시 연산자에 대한 최적의 조합을 계산하는 것보다 쉬움
  • 연산자 방식 장점
    • 수정할 도큐먼트를 가져오기 위한 조회가 필요 없음
    • 업데이트를 지정할 도큐먼트 크기가 일반적으로 작음
    • 원자적으로 업데이트 시 적합

2. 원자적 도큐먼트 프로세싱

  • 다른 연산이 인터럽트하거나 인터리브 할 수 없는 업데이트
  • 모든 업데이트는 원자적이지만 findAndModify는 도큐먼트 자동 반환
  • findAndModify는 default로 업데이트 이전 도큐먼트 반환
  • new: true 옵션을 추가해주면 업데이트 이후의 도큐먼트 반환
// 업데이트 이후 도큐먼트
newDoc = db.orders.findAndModify({
    query: {
        user_id: ObjectId("4c4b1476238d3b4dd5000001"),
        state: 'CART'
    },
    update: {
        $set: {
            state: 'PRE-AUTHORIZE'
        }
    },
    'new': true // 업데이트 이후의 도큐먼트 반환 옵션
})

// 업데이트 이전 도큐먼트
oldDoc = db.orders.findAndModify({
    query: {
        user_id: ObjectId("4c4b1476238d3b4dd5000001"),
        total: 99000,
        state: "PRE-AUTHORIZE"
    },
    update: {
        '$set': {
            state: "AUTHORIZING"
        }
    }
})

3. MongoDB 업데이트와 삭제

3.1 업데이트 타입과 옵션

  • 타깃 방식과 대치 방식 업데이트 지원
  • 도큐먼트가 모오하면 업데이트는 실패
// 도큐먼트 이름 변경
// 쿼리 셀렉터와 일치하는 첫 번째 도큐먼트만을 업데이트
db.products.update_one({},
    {$set: {name: "Pitchfork"}, $addToSet: {tags: 'cheap'}})

// 다중 도큐먼트 업데이트
// 일치하는 도큐먼트 모두 업데이트를 위해 multi: true 매개변수 추가 필요
db.products.update({}, {$addToSet: {tags: 'cheap'}}, {multi: true})
  • 업서트
    • 도큐먼트가 없을 경우 새로 추가하고 이미 있다면 업데이트 처리
    • 대치 방식의 업데이트에서는 수행 X
db.products.update({slug: 'hammer'},
    {$addToSet: {tags: 'cheap'}}, {upsert: true})

3.2 업데이트 연산자

  • 연산자
    • $inc : 주어진 값에 따라 필드 값 증가
    • $set : 필드를 주어진 값으로 설정
    • $unsert : 전달받은 필드의 설정을 해제
    • $rename : 필드의 이름을 주어진 값으로 변경
    • $setOnInsert : upsert에서 삽입이 발생할 때만 필드를 설정
    • $bit : 필드의 비트 단위 업데이트를 수행
  • 배열 연산자
    • $ : 쿼리 셀렉터에 의해 발견된 위치에서 하위 도큐먼트를 업데이트
    • $push : 배열에 값을 추가
    • $pushAll : 배열에 값 배열을 추가. 더 이상 사용되지 않고 대신 $each를 사용
    • $addToSet : 배열에 값을 추가하지만 그것이 중복되면 아무것도 하지 않음
    • $pop : 배열의 첫 번째 또는 마지막 항목을 제거
    • $pull : 주어진 쿼리와 일치하는 배열에서 값을 제거
    • $pullAll : 배열에서 여러 값을 제거
  • 배열 연산자 수정자
    • $each : 이 연산자를 여러 값에 적응하려면 $push 및 $addToSet과 함께 사용
    • $slice : $push 및 $each와 함께 사용하여 업데이트된 배열을 특정 크기로 분할
    • $sort : 분할하기 전에 $push, $each 및 $slice와 함께 배열의 하위 도큐먼트를 정렬하는 데 사용
  • 독립 연산
    • $isolated : 여러 도큐먼트 업데이트에 다른 연산이 끼어드는 것을 허용하지 않음

3.3 findAndModify 명령

  • 수정 전 또는 이후의 도큐먼트 반환
    • default : 수정 전 도큐먼트 반환
    • new: true 옵션을 추가해주면 업데이트 이후의 도큐먼트 반환
  • 삭제, 대체, 갱신이라는 세 가지 작업의 기능을 결함한 메서드로 사용자 오류가 발생하기 쉬움
  • 3.2 버전에서 findAndModify을 수용한 3개의 컬렉션 메서드 추가
    • findOneAndDelete
    • findOneAndReplace
    • findOneAndUpdate
    • new 대신 returnNewDocument 필드 사용
doc = db.orders.findAndModify({
    query: {
        user_id: ObjectId("4c4b1476238d3b4dd5000001"),
    },
    update: {
        $set: {
            state: "AUTHORIZING"
        }
    }
})

3.4 삭제

// 모든 리뷰 삭제
db.reviews.remove({})
// 특정 사용자 리뷰 삭제
db.reviews.remove({user_id: ObjectId('4c4b1476238d3b4dd5000001')})

출처

  • MongoDB in Action 2nd
  • MongoDB 완벽 가이드

'dev > DB' 카테고리의 다른 글

이력관리  (0) 2022.03.22
MongoDB - 인덱스1  (0) 2021.12.23
MongoDB - 집계2  (0) 2021.11.04
MongoDB - 집계1  (0) 2021.10.28
MongoDB - Query Selectors(1)  (0) 2021.10.22
profile

Notepad

@Apio

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!