대량 작업
개요
이 가이드에서는 MongoDB 코틀린(Kotlin) 드라이버에서 대량 작업을 사용하는 방법을 배울 수 있습니다.
개별 CRUD 작업의 경우 관련 메서드를 사용할 수 있습니다. 예를 들어, 하나의 문서를 삽입한 다음 여러 문서를 업데이트하려면 insertOne()
메서드와 updateMany()
메서드를 사용할 수 있습니다.
MongoClient
는 각 작업에 해당하는 데이터베이스에 요청하여 이러한 작업을 수행합니다. 대량 작업을 사용하여 데이터베이스에 대한 호출 수를 줄일 수 있습니다.
대량 작업 수행
대량 작업은 다수의 쓰기 작업으로 구성됩니다. 일괄 작업을 수행하려면 WriteModel
문서가 포함된 List
을 bulkWrite()
메서드에 전달합니다. WriteModel
는 단일 쓰기 작업을 나타내는 모델입니다.
다음 섹션에서는 WriteModel
유형의 각 변형을 만들고 사용하는 방법을 보여 줍니다. 각 섹션의 예제에서는 people
collection의 다음 문서를 사용합니다.
{ "_id": 1, "name": "Karen Sandoval", "age": 31 } { "_id": 2, "name": "William Chin", "age": 54 } { "_id": 8, "name": "Shayla Ray", "age": 20 }
이 데이터는 다음 Kotlin 데이터 클래스로 모델링됩니다.
data class Person( val id: Int, val name: String, val age: Int? = null, val location: String? = null )
이 섹션에 언급된 메서드 및 클래스에 대한 자세한 내용은 다음 API 문서를 참조하세요.
삽입 작업
삽입 작업을 수행하려면 삽입하려는 문서를 지정하는 InsertOneModel
을 만듭니다. 여러 문서를 삽입하려면 삽입하려는 각 문서에 대해 InsertOneModel
을 만듭니다.
예시
다음 예에서는 사람을 설명하는 두 문서에 대해 InsertOneModel
을 만듭니다.
val juneDoc = InsertOneModel(Person(3, "June Carrie", 17)) val kevinDoc = InsertOneModel(Person(4, "Kevin Moss", 22))
중요
bulkWrite()
작업을 수행할 때 InsertOneModel
은 collection에 이미 존재하는 _id
가 포함된 문서를 삽입할 수 없습니다. 이 경우 드라이버는 MongoBulkWriteException
을 발생시킵니다.
다음 예에서는 _id
값이 1
및 3
인 두 문서를 삽입하려고 시도합니다. collection에 1
의 _id
이 있는 문서가 이미 있으므로 이 작업을 수행하면 오류가 발생합니다.
try { val bulkOperations = listOf( (InsertOneModel(Person(1, "James Smith", 13))), (InsertOneModel(Person(3, "Colin Samuels"))) ) val bulkWrite = collection.bulkWrite(bulkOperations) } catch (e: MongoBulkWriteException) { println("A MongoBulkWriteException occurred with the following message: " + e.message) }
A MongoBulkWriteException occurred with the following message: Bulk write operation error on server sample-shard-00-02.pw0q4.mongodb.net:27017. Write errors: [BulkWriteError{index=0, code=11000, message='E11000 duplicate key error collection: crudOps.bulkWrite index: _id_ dup key: { _id: 1 }', details={}}].
드라이버가 3
_id
인 문서를 삽입하지 않은 이유에 대해 알아보려면 실행 순서 섹션을 참조하세요.
이 섹션에 언급된 메서드 및 클래스에 대한 자세한 내용은 InsertOneModel API 설명서를 참조하세요.
대체 작업
대체 작업을 수행하려면 대체하려는 문서와 대체 문서에 대한 쿼리 필터를 지정하는 ReplaceOneModel
을 만듭니다.
중요
bulkWrite()
를 수행할 때 ReplaceOneModel
은 collection의 고유 인덱스 제약 조건을 위반하는 변경을 수행할 수 없습니다. 또한 쿼리 필터와 일치하는 항목이 없는 경우 모델은 바꾸기 작업을 수행하지 않습니다.
예시
다음 예에서는 _id
가 1
인 문서를 추가 location
필드가 포함된 문서로 대체하기 위해 ReplaceOneModel
을 만듭니다.
val filter = Filters.eq("_id", 1) val insert = Person(1, "Celine Stork", location = "San Diego, CA") val doc = ReplaceOneModel(filter, insert)
이 섹션에 언급된 메서드 및 클래스에 대한 자세한 내용은 다음 API 리소스를 참조하세요.
ReplaceOneModel API 설명서
고유 인덱스 서버 매뉴얼 설명
업데이트 작업
업데이트 작업을 수행하려면 쿼리 필터와 업데이트 문서를 지정하는 UpdateOneModel
또는 UpdateManyModel
를 만듭니다.
UpdateOneModel
은 쿼리 필터와 일치하는 첫 번째 문서를 업데이트하고, UpdateManyModel
은 쿼리 필터와 일치하는 모든 문서를 업데이트합니다.
중요
bulkWrite()
를 수행할 때 UpdateOneModel
및 UpdateManyModel
유형은 collection의 고유 인덱스 제약 조건을 위반하는 변경을 수행할 수 없습니다. 또한 쿼리 필터와 일치하는 항목이 없는 경우 모델은 업데이트 작업을 수행하지 않습니다.
예시
다음 예시에서는 _id
가 2
인 문서에서 age
필드를 1
만큼 증가시키는 UpdateOneModel
을 만듭니다.
val filter = Filters.eq("_id", 2) val update = Updates.inc(Person::age.name, 1) val doc = UpdateOneModel<Person>(filter, update)
이 섹션에 언급된 메서드 및 클래스에 대한 자세한 내용은 다음 API 리소스를 참조하세요.
UpdateOneModel API 설명서
UpdateManyModel API 설명서
고유 인덱스 서버 매뉴얼 설명
삭제 작업
삭제 작업을 수행하려면 삭제하려는 문서에 대한 쿼리 필터를 지정하는 DeleteOneModel
또는 DeleteManyModel
를 만듭니다.
DeleteOneModel
은 쿼리 필터와 일치하는 첫 번째 문서를 삭제하고 DeleteManyModel
은 쿼리 필터와 일치하는 모든 문서를 삭제합니다.
중요
bulkWrite()
수행 시 DeleteOneModel
및 DeleteManyModel
유형은 쿼리 필터와 일치하는 항목이 없는 경우 문서를 삭제하지 않습니다.
예시
다음 예에서는 _id
가 1
인 문서를 삭제하기 위해 DeleteOneModel
을 만들고 age
값이 30
보다 작은 문서를 삭제하기 위해 DeleteManyModel
을 만듭니다.
val deleteId1 = DeleteOneModel<Person>(Filters.eq("_id", 1)) val deleteAgeLt30 = DeleteManyModel<Person>(Filters.lt(Person::age.name, 30))
이 섹션에 언급된 메서드 및 클래스에 대한 자세한 내용은 다음 API 문서를 참조하세요.
실행 순서
bulkWrite()
메서드는 선택적 BulkWriteOptions
을 두 번째 매개 변수로 허용하여 대량 작업을 순서가 지정된 작업으로 실행할지, 순서가 지정되지 않은 상태로 실행할지 여부를 지정합니다.
순서 지정된 실행
기본적으로 bulkWrite()
메서드는 대량 작업을 순서대로 실행합니다. 즉, 오류가 발생할 때까지 목록에 추가한 순서대로 작업이 실행됩니다.
예시
다음 예에서는 아래의 대량 작업을 수행합니다.
name
이(가)"Zaynab Omar"
이고age
이(가)37
인 문서에 대한 삽입 작업입니다._id
가1
인 문서를location
필드가 포함된 새 문서로 대체하는 작업_id
이6
인 문서에 대한 업데이트 작업을 수행하여name
필드를 변경합니다.age
값이50
보다 큰 모든 문서에 대한 삭제 작업
val insertMdl = InsertOneModel(Person(6, "Zaynab Omar", 37)) val replaceMdl = ReplaceOneModel( Filters.eq("_id", 1), Person(1, "Sandy Kane", location = "Helena, MT") ) val updateMdl = UpdateOneModel<Person>( Filters.eq("_id", 6), Updates.set(Person::name.name, "Zaynab Hassan") ) val deleteMdl = DeleteManyModel<Person>(Filters.gt(Person::age.name, 50)) val bulkOperations = listOf( insertMdl, replaceMdl, updateMdl, deleteMdl ) val result = collection.bulkWrite(bulkOperations)
이 예시가 실행된 후에는 컬렉션에 다음 문서가 포함됩니다.
{ "_id": 1, "name": "Sandy Kane", "location": "Helena, MT" } { "_id": 8, "name": "Shayla Ray", "age": 20 } { "_id": 6, "name": "Zaynab Hassan", "age": 37 }
순서 지정되지 않은 실행
BulkWriteOptions
객체의 ordered()
메서드에 false
을 전달하여 순서에 상관없이 대량 작업을 실행할 수도 있습니다. 즉, 오류와 관계없이 모든 쓰기 작업이 실행됩니다. 오류가 발생하면 드라이버는 마지막에 오류를 보고합니다.
다음 코드는 실행 순서 없이 대량 작업을 실행하는 방법을 보여줍니다.
val options = BulkWriteOptions().ordered(false) val unorderedResult = collection.bulkWrite(bulkOperations, options)
참고
순서가 지정되지 않은 대량 작업은 실행 순서를 보장하지 않습니다. 순서는 런타임을 최적화하기 위해 나열한 방식과 다를 수 있습니다.
앞의 예에서 bulkWrite()
메서드가 업데이트 작업 후에 삽입 작업을 수행한 경우 해당 시점에 문서가 존재하지 않았으므로 업데이트 작업은 변경 사항을 생성하지 않습니다. 그러면 collection에 다음 문서가 포함됩니다.
{ "_id": 1, "name": "Sandy Kane", "location": "Helena, MT" } { "_id": 8, "name": "Shayla Ray", "age": 20 } { "_id": 6, "name": "Zaynab Omar", "age": 37 }
이 섹션에 언급된 메서드 및 클래스에 대한 자세한 내용은 다음 API 문서를 참조하세요.
요약
일괄 작업을 수행하려면 WriteModel
문서 목록을 만들어 bulkWrite()
메서드에 전달합니다.
WriteModel
에는 6가지 변형이 있습니다.
InsertOneModel
ReplaceOneModel
UpdateOneModel
UpdateManyModel
DeleteOneModel
DeleteManyModel
bulkWrite()
메서드를 실행하는 방법에는 두 가지가 있습니다.
순서가 지정됨, 드라이버가 오류가 발생할 때까지 쓰기 작업을 순서대로 수행합니다.
순서가 지정되지 않음, 드라이버가 모든 쓰기 작업을 순서에 상관없이 수행하고 작업이 완료된 후 오류를 보고합니다.