Database/Mongo

유용한 Query 함수들

Jeffrey Oh 2023. 3. 6. 16:00
반응형

bulkWrite

db.bulk.bulkWrite(
    [
        { insertOne: { doc: 1, order: 1 } },
        { insertOne: { doc: 2, order: 2 } },
        { insertOne: { doc: 3, order: 3 } },
        { insertOne: { doc: 4, order: 4 } },
        { insertOne: { doc: 5, order: 5 } },
        { insertOne: { doc: 6, order: 6 } },
        {
            deleteOne: {
                filter: { doc: 3 }
            }
        },
        {
            updateOne: {
                filter: { doc: 2 },
                update: {
                    $set: { doc: 12 }
                }
            }
        }
    ]
)

ordered 옵션을 사용하면 수행될 Operation 의 순서에 상관없이 실행되며
수행되어야할 document 가 많고 순서가 상관 없는 경우에 유용하다.
예제에서는 개수가 적어서 별차이가 없으며 위의 예제 코드와 동일한 결과를 나타낸다.

db.bulk.bulkWrite(
    [
        { insertOne: { doc: 1, order: 1 } },
        { insertOne: { doc: 2, order: 2 } },
        { insertOne: { doc: 3, order: 3 } },
        { insertOne: { doc: 4, order: 4 } },
        { insertOne: { doc: 5, order: 5 } },
        { insertOne: { doc: 6, order: 6 } },
        {
            updateOne: {
                filter: { doc: 2 },
                update: {
                    $set: { doc: 3 }
                }
            }
        },
        {
            deleteMany: {
                filter: { doc: 3 }
            }
        },
    ],
    { ordered: false }
)

countDocuments, estimatedDocumentCount

카운트 함수로 각각 수행되는 과정이 다름

db.bulk.countDocuments() // 실제 수행
db.bulk.estimatedDocumentCount() // 예상되는 값을 출력

distinct

선택한 필드를 중복을 제거하고 조회한다

db.bulk.distinct("doc")

findAndModify

findAndModify 함수는 findOneAnd**** 함수들로 분리되어 별도로 존재하기도 함
findOneAndDelete()
findOneAndReplace()
findOneAndUpdate()

db.bulk.findAndModify({
    query: { doc: 4 },
    update: { $inc : { doc: 1 } }
})

findAndModify 함수는 document 를 1개씩만 실행시키며 전체 실행되지 않는다.

아래는 순서에 대해 먼저 정렬 후 수정 실행

db.bulk.findAndModify({
    query: { doc: 5 },
    sort: { order: -1 }, // 내림차순
    update: { $inc : { doc: 1 } }
})

동시성 제어의 문제는 findmodify 를 서로 각자 실행하는 경우 발생하며 이를 한번에 Atomic 하게 처리하려면 findAndModify 를 사용해야 한다.

db.sequence.insertOne({ seq: 0 })

seq 가 0인 document 를 조회하여 값을 수정하는 경우에 동시성 문제를 예방하려면 다음과 같이 실행

db.sequence.findAndModify({
    query: {}, // {} - 전부 처리
    sort: { seq: -1 },
    update: { $inc: { seq: 1 } }
})

하지만 이는 1개의 document 에 대한 동시성 문제만 해결될 뿐 여러 document 의 동시성 문제는 transaction 으로 다뤄야하는 것 같음


getIndexes

현재 생성된 index 를 목록으로 보여줌

db.bulk.getIndexes()

index 를 하나 추가하고 다시 확인 해보자

db.bulk.createIndex({ doc: 1 })
db.bulk.getIndexes()

replace, update

update 는 field 를 수정할 때 사용하지만 replace 는 document 전체를 수정하는 것
따라서 replace 를 사용하여 명시한 field 만 대체되고 명시되지 않은 field 는 삭제된다

db.bulk.updateOne({ doc: 1 }, { $set: { _id: 1 } })
db.bulk.replaceOne({ doc: 1 }, { _id: 1, doc: 13 })
MongoServerError: Performing an update on the path '_id' would modify the immutable field '_id'

mongodb 는 _id field 가 한번 정의되면 수정할 수 없음 (immutable)

반응형