문서 메뉴
문서 홈
/
MongoDB 매뉴얼
/ / /

db.collection.bulkWrite()

이 페이지의 내용

  • 정의
  • 호환성
  • 구문
  • 행동
  • 예제
db.collection.bulkWrite()

중요

Mongo쉬 방법

이 페이지에서는 mongosh 메서드를 설명합니다. 이는 Node.js와 같은 언어별 드라이버에 대한 설명서가 아닙니다.

MongoDB API 드라이버의 경우 언어별 MongoDB 드라이버 설명서를 참조하세요.

실행 순서를 제어하여 여러 쓰기 작업을 수행합니다.

반환합니다:
  • 작업이 쓰기 고려와 함께 실행된 경우 부울 acknowledgedtrue 로, 쓰기 고려가 비활성화된 경우 false 를 반환합니다.
  • 각 쓰기 작업의 개수입니다.
  • 성공적으로 삽입되거나 업스트된 각 문서에 대해 _id를 포함하는 배열입니다.

다음 환경에서 호스팅되는 배포에 db.collection.bulkWrite() 사용할 수 있습니다.

  • MongoDB Atlas: 클라우드에서의 MongoDB 배포를 위한 완전 관리형 서비스

참고

Atlas UI 에서는 대량 쓰기 작업을 수행할 수 없습니다. 여러 문서를 삽입하려면 문서 배열을 삽입해야 합니다. 자세히 알아보려면 Atlas 문서에서 문서 생성, 보기, 업데이트 및 삭제를 참조하세요.

bulkWrite() 메서드의 형식은 다음과 같습니다.

db.collection.bulkWrite(
[ <operation 1>, <operation 2>, ... ],
{
writeConcern : <document>,
ordered : <boolean>
}
)

bulkWrite() 메서드는 다음 매개변수를 사용합니다.

매개 변수
유형
설명
operations
배열

bulkWrite() 쓰기 작업의 배열입니다.

유효한 연산은 다음과 같습니다.

각 작업의 사용법은 쓰기 작업을 참조하세요.

writeConcern
문서

선택 사항입니다. 쓰기 고려를 표현하는 문서입니다. 기본 쓰기 고려를 사용하지 않으려면 생략하세요.

트랜잭션에서 실행되는 경우 작업에 대한 쓰기 고려를 명시적으로 설정하지 마세요. 트랜잭션에 쓰기 고려를 사용하려면 트랜잭션 및 쓰기 고려를 참조하세요.

ordered
부울

선택 사항입니다. mongod 인스턴스가 정렬된 작업을 실행할지 아니면 정렬되지 않은 작업을 실행할지 지정하는 부울입니다. 기본값은 true입니다.

작업 실행을 참조하세요.

bulkWrite()은 쓰기 작업의 배열을 가져와서 각 작업을 실행합니다. 기본적으로 작업은 순서대로 실행됩니다. 쓰기 작업 실행 순서를 제어하려면 작업 실행을 참조하세요.

단일 문서를 collection에 삽입합니다.

db.collection.bulkWrite( [
{ insertOne : { "document" : <document> } }
] )

db.collection.insertOne()참조하십시오.

필드
참고 사항
filter
업데이트의 선택 기준입니다. 메서드와 동일한 쿼리 선택기db.collection.find() 사용할 수 있습니다.
update

수행할 업데이트 작업입니다. 다음 중 하나를 지정할 수 있습니다.

upsert

선택 사항. 업서트를 수행할지 여부를 나타내는 부울입니다.

기본적으로 upsertfalse입니다.

arrayFilters
선택 사항입니다. 필터 문서의 배열로, 배열 필드에 대한 업데이트 작업을 위해 수정할 배열 요소를 결정합니다.
collation
선택 사항입니다. 작업에 사용할 데이터 정렬을 지정합니다.
hint
선택 사항입니다. filter 업데이트를 지원하는 데 사용할 인덱스입니다. 존재하지 않는 인덱스를 지정하면 연산 오류가 발생합니다.

자세한 내용은 db.collection.updateOne()db.collection.updateMany()를 참조하세요.

replaceOne 컬렉션에서 필터와 일치하는 단일 문서를 대체합니다. 여러 문서가 일치하는 경우 replaceOne첫 번째 일치하는 문서만 대체합니다.

db.collection.bulkWrite([
{ replaceOne :
{
"filter" : <document>,
"replacement" : <document>,
"upsert" : <boolean>,
"collation": <document>,
"hint": <document|string>
}
}
] )
필드
참고 사항
filter
교체 작업의 선택 기준입니다. db.collection.find() 메서드에서와 동일한 쿼리 선택기를 사용할 수 있습니다.
replacement
대체 문서입니다. 문서에는 업데이트 연산자가 포함될 수 없습니다.
upsert
선택 사항. 업서트를 수행할지 여부를 나타내는 부울입니다. 기본적으로 upsertfalse입니다.
collation
선택 사항입니다. 작업에 사용할 데이터 정렬을 지정합니다.
hint
선택 사항입니다. filter 업데이트를 지원하는 데 사용할 인덱스입니다. 존재하지 않는 인덱스를 지정하면 연산 오류가 발생합니다.

자세한 내용은 db.collection.replaceOne()을 참고하세요.

필드
참고 사항
filter
삭제 작업의 선택 기준입니다. db.collection.find() 메서드에서와 동일한 쿼리 선택기를 사용할 수 있습니다.
collation
선택 사항입니다. 작업에 사용할 데이터 정렬을 지정합니다.

자세한 내용은 db.collection.deleteOne()db.collection.deleteMany()를 참조하세요.

문서에 _id 필드가 지정되지 않은 경우 mongod에서 _id 필드를 추가하고 삽입 또는 업서트하기 전에 문서에 고유한 ObjectId()를 할당합니다. 대부분의 드라이버는 객체 ID를 생성하고 _id 필드를 삽입하지만, 드라이버나 애플리케이션이 수행하지 않는 경우 mongod에서 _id를 생성하여 채웁니다.

문서에 _id 필드가 포함된 경우 중복 키 오류를 방지하려면 _id 값이 컬렉션 내에서 고유해야 합니다.

업데이트 또는 교체 작업에서는 원본 문서와 다른 _id 값을 지정할 수 없습니다.

ordered 매개변수는 bulkWrite()이 작업을 순서대로 실행할지 여부를 지정합니다. 기본적으로 작업은 순서대로 실행됩니다.

다음 코드는 연산이 5개 포함된 bulkWrite()를 나타냅니다.

db.collection.bulkWrite(
[
{ insertOne : <document> },
{ updateOne : <document> },
{ updateMany : <document> },
{ replaceOne : <document> },
{ deleteOne : <document> },
{ deleteMany : <document> }
]
)

기본값 ordered : true 상태에서는 첫 번째 연산 insertOne부터 마지막 연산 deleteMany까지 각 연산이 순서대로 실행됩니다.

ordered를 거짓으로 설정하면 성능을 높이기 위해 mongod로 작업 순서를 변경할 수 있습니다. 애플리케이션은 작업 실행 순서에 의존해서는 안 됩니다.

다음 코드는 연산 6개가 포함된 정렬되지 않은 bulkWrite()를 나타냅니다.

db.collection.bulkWrite(
[
{ insertOne : <document> },
{ updateOne : <document> },
{ updateMany : <document> },
{ replaceOne : <document> },
{ deleteOne : <document> },
{ deleteMany : <document> }
],
{ ordered : false }
)

ordered : false을 사용하면 연산 결과가 달라질 수 있습니다. 예를 들어 deleteOne 또는 deleteManyinsertOne, updateOne, updateMany 또는 replaceOne 작업의 이전 또는 이후 실행 여부에 따라 더 많은 문서 또는 더 적은 문서를 제거할 수 있습니다.

각 그룹의 작업 수는 데이터베이스의 maxWriteBatchSize 값을 초과할 수 없습니다. MongoDB 3.6부터 이 값은 100,000 입니다. 이 값은 hello.maxWriteBatchSize 필드에 표시됩니다.

이 제한은 오류 메시지의 크기가 너무 커지는 문제를 방지합니다. 그룹이 이 제한을 초과하면 클라이언트 드라이버는 그룹을 제한 값보다 작거나 같은 수의 작은 그룹으로 나눕니다. 예를 들어 maxWriteBatchSize 값이 100,000인 경우 대기열이 200,000개의 작업으로 구성되어 있으면 드라이버는 각각 100,000개의 작업이 있는 2개의 그룹을 만듭니다.

참고

이 드라이버는 고급 API를 사용할 때에만 그룹을 작은 그룹으로 나눕니다. db.runCommand() 를 직접 사용하는 경우(예: 드라이버를 작성할 때), 제한을 초과하는 쓰기 배치를 실행하려고 할 때 MongoDB에서 오류가 발생합니다.

MongoDB 3.6부터 단일 배치에 대한 오류 보고서가 너무 커지면 MongoDB는 나머지 모든 오류 메시지를 빈 문자열로 자릅니다. 현재는 총 크기가 1MB 보다 큰 오류 메시지가 2개 이상 있는 경우 시작됩니다.

크기 및 그룹화 메커니즘은 내부 성능 세부 정보이며 향후 버전에서 변경될 수 있습니다.

샤드 컬렉션에서 ordered 작업 목록을 실행하는 것은 unordered 목록을 실행하는 것보다 일반적으로 느립니다. 정렬된 목록에서는 각 작업이 이전 작업이 완료될 때까지 기다려야 하기 때문입니다.

bulkWrite() 쓰기 작업은 고정 사이즈 컬렉션에서 사용할 때 제한이 있습니다.

updateOneupdateManyWriteError를 발생시킵니다(update 기준으로 인해 수정되는 문서의 크기가 커지는 경우).

replaceOnereplacement 문서의 크기가 원본 문서보다 큰 경우 WriteError를 발생시킵니다.

deleteOnedeleteMany은(는) 고정 사이즈 컬렉션에 사용하면 WriteError을(를) 발생시킵니다.

bulkWrite() 쓰기 작업은 time series 컬렉션에서 사용할 때 제한이 있습니다. time series 컬렉션에는 insertOne 만 사용할 수 있습니다. 다른 모든 작업은 WriteError를 반환합니다.

db.collection.bulkWrite()는 오류 발생 시 BulkWriteError 예외를 발생시킵니다(작업이 MongoDB 4.0에서 트랜잭션의 일부가 아닌 경우). 트랜잭션 내부의 오류 처리를 참조하세요.

쓰기 고려 오류를 제외하고 순서가 지정된 작업은 오류 발생 후 중지되는 반면, 순서가 지정되지 않은 작업은 트랜잭션 내에서 실행되지 않는 한 대기열에 남아 있는 쓰기 작업을 계속 처리합니다. 트랜잭션 내부의 오류 처리를 참조하세요.

쓰기 고려 오류는 writeConcernErrors 필드에 표시되고 기타 모든 오류는 writeErrors 필드에 표시됩니다. 오류가 발생하면 입력된 _id 값 대신 성공한 쓰기 연산의 수가 표시됩니다. 순서가 지정된 연산에서는 발생한 단일 오류가 표시됩니다. 한편 순서가 지정되지 않은 연산에서는 각 오류가 한 배열에 표시됩니다.

db.collection.bulkWrite()분산 트랜잭션 내에서 사용할 수 있습니다.

중요

대부분의 경우 분산 트랜잭션은 단일 문서 쓰기에 비해 더 큰 성능 비용이 발생하므로 분산 트랜잭션의 가용성이 효과적인 스키마 설계를 대체할 수는 없습니다. 대부분의 시나리오에서 비정규화된 데이터 모델 (내장된 문서 및 배열) 은 계속해서 데이터 및 사용 사례에 최적일 것입니다. 즉, 대부분의 시나리오에서 데이터를 적절하게 모델링하면 분산 트랜잭션의 필요성이 최소화됩니다.

추가 트랜잭션 사용 고려 사항(예: 런타임 제한 및 oplog 크기 제한)은 프로덕션 고려사항을 참조하세요.

기능 호환성 버전(fcv) "4.4" 이상의 경우, 존재하지 않는 컬렉션에 대해 트랜잭션에서 upsert: true로 삽입 연산 또는 업데이트 연산을 실행하면 컬렉션이 암시적으로 생성됩니다.

참고

샤드 간 쓰기 트랜잭션에서는 새 컬렉션을 생성할 수 없습니다. 예를 들어, 하나의 샤드에서 기존 컬렉션에 쓰고 다른 샤드에서 암시적으로 새 컬렉션을 생성하는 경우, MongoDB는 동일한 트랜잭션에서 두 작업을 모두 수행할 수 없습니다.

트랜잭션에서 실행되는 경우 작업에 대한 쓰기 고려를 명시적으로 설정하지 마세요. 트랜잭션에 쓰기 고려를 사용하려면 트랜잭션 및 쓰기 고려를 참조하세요.

MongoDB 4.2부터 db.collection.bulkWrite() 연산이 트랜잭션 내부에서 오류가 발생하면 이 메서드는(트랜잭션 외부에서와 동일하게) BulkWriteException을 발생시킵니다.

4.0에서는 bulkWrite 연산의 트랜잭션 내부에서 오류가 발생할 경우, 발생한 오류가 BulkWriteException(으)로 래핑되지 않습니다.

대량 쓰기의 순서가 지정되지 않은 경우에도 트랜잭션 내부에서는 대량 쓰기의 첫 오류로 인해 대량 쓰기 전체가 실패하고 트랜잭션이 중단됩니다.

bulkWrite() 작업 순서 및 오류 처리를 이해하는 것이 중요합니다. 기본적으로 bulkWrite() (은)는 순서가 지정된 작업 목록을 실행합니다.

  • 작업은 연속적으로 실행됩니다.

  • 작업에 오류가 있는 경우 해당 작업과 이후 작업은 실행되지 않습니다.

  • 오류 작업 이전에 나열된 작업이 완료되었습니다.

다음 bulkWrite() 예시에서는 pizzas 컬렉션을 사용합니다.

db.pizzas.insertMany( [
{ _id: 0, type: "pepperoni", size: "small", price: 4 },
{ _id: 1, type: "cheese", size: "medium", price: 7 },
{ _id: 2, type: "vegan", size: "large", price: 8 }
] )

다음 bulkWrite() 예시에서는 이러한 작업을 pizzas 컬렉션에서 실행합니다.

  • 0}을 사용하여 두 개의 문서를 추가합니다.insertOne

  • 0}을 사용하여 문서를 업데이트합니다.updateOne

  • 0}을(를) 사용하여 문서를 삭제합니다.deleteOne

  • 0}을 사용하여 문서를 바꿉니다.replaceOne

try {
db.pizzas.bulkWrite( [
{ insertOne: { document: { _id: 3, type: "beef", size: "medium", price: 6 } } },
{ insertOne: { document: { _id: 4, type: "sausage", size: "large", price: 10 } } },
{ updateOne: {
filter: { type: "cheese" },
update: { $set: { price: 8 } }
} },
{ deleteOne: { filter: { type: "pepperoni"} } },
{ replaceOne: {
filter: { type: "vegan" },
replacement: { type: "tofu", size: "small", price: 4 }
} }
] )
} catch( error ) {
print( error )
}

완료된 작업의 요약을 포함하는 예제 출력:

{
acknowledged: true,
insertedCount: 2,
insertedIds: { '0': 3, '1': 4 },
matchedCount: 2,
modifiedCount: 2,
deletedCount: 1,
upsertedCount: 0,
upsertedIds: {}
}

이전 bulkWrite() 예제를 실행하기 전에 컬렉션에 _id4 인 문서가 이미 포함되어 있는 경우, 두 번째 insertOne 작업에 대해 다음과 같은 중복 키 예외가 반환됩니다.

writeErrors: [
WriteError {
err: {
index: 1,
code: 11000,
errmsg: 'E11000 duplicate key error collection: test.pizzas index: _id_ dup key: { _id: 4 }',
op: { _id: 4, type: 'sausage', size: 'large', price: 10 }
}
}
],
result: BulkWriteResult {
result: {
ok: 1,
writeErrors: [
WriteError {
err: {
index: 1,
code: 11000,
errmsg: 'E11000 duplicate key error collection: test.pizzas index: _id_ dup key: { _id: 4 }',
op: { _id: 4, type: 'sausage', size: 'large', price: 10 }
}
}
],
writeConcernErrors: [],
insertedIds: [ { index: 0, _id: 3 }, { index: 1, _id: 4 } ],
nInserted: 1,
nUpserted: 0,
nMatched: 0,
nModified: 0,
nRemoved: 0,
upserted: []
}
}

bulkWrite() 예시는 순서가 지정되어 있으므로 첫 번째 insertOne 작업만 완료됩니다.

오류가 없는 모든 작업을 완료하려면 orderedfalse로 설정한 상태에서 bulkWrite()를 실행합니다. 예를 들어 다음 섹션을 참조하세요.

순서가 지정되지 않은 bulkWrite()를 지정하려면 orderedfalse로 설정합니다.

순서가 지정되지 않은 bulkWrite() 연산 목록에서:

pizzas collection 예시를 계속 진행하여 collection을 삭제하고 다시 생성합니다.

db.pizzas.insertMany( [
{ _id: 0, type: "pepperoni", size: "small", price: 4 },
{ _id: 1, type: "cheese", size: "medium", price: 7 },
{ _id: 2, type: "vegan", size: "large", price: 8 }
] )

다음 예시를 살펴보겠습니다.

  • bulkWrite()pizzas 컬렉션에서 순서가 지정되지 않은 작업을 실행합니다.

  • 두 번째 insertOne 작업에는 첫 번째 insertOne 와 동일한 _id 있으므로 중복 키 오류가 발생합니다.

try {
db.pizzas.bulkWrite( [
{ insertOne: { document: { _id: 3, type: "beef", size: "medium", price: 6 } } },
{ insertOne: { document: { _id: 3, type: "sausage", size: "large", price: 10 } } },
{ updateOne: {
filter: { type: "cheese" },
update: { $set: { price: 8 } }
} },
{ deleteOne: { filter: { type: "pepperoni"} } },
{ replaceOne: {
filter: { type: "vegan" },
replacement: { type: "tofu", size: "small", price: 4 }
} }
],
{ ordered: false } )
} catch( error ) {
print( error )
}

중복 키 오류와 완료된 작업의 요약을 포함하는 예시 출력:

writeErrors: [
WriteError {
err: {
index: 1,
code: 11000,
errmsg: 'E11000 duplicate key error collection: test.pizzas index: _id_ dup key: { _id: 3 }',
op: { _id: 3, type: 'sausage', size: 'large', price: 10 }
}
}
],
result: BulkWriteResult {
result: {
ok: 1,
writeErrors: [
WriteError {
err: {
index: 1,
code: 11000,
errmsg: 'E11000 duplicate key error collection: test.pizzas index: _id_ dup key: { _id: 3 }',
op: { _id: 3, type: 'sausage', size: 'large', price: 10 }
}
}
],
writeConcernErrors: [],
insertedIds: [ { index: 0, _id: 3 }, { index: 1, _id: 3 } ],
nInserted: 1,
nUpserted: 0,
nMatched: 2,
nModified: 2,
nRemoved: 1,
upserted: []
}
}

중복 키 오류로 인해 두 번째 insertOne 연산이 실패했습니다. 순서가 지정되지 않은 bulkWrite()에서 오류가 없는 모든 작업이 완료됩니다.

pizzas collection 예시를 계속 진행하여 collection을 삭제하고 다시 생성합니다.

db.pizzas.insertMany( [
{ _id: 0, type: "pepperoni", size: "small", price: 4 },
{ _id: 1, type: "cheese", size: "medium", price: 7 },
{ _id: 2, type: "vegan", size: "large", price: 8 }
] )

다음 bulkWrite() 예시에서는 pizzas 컬렉션에서 작업을 실행하고 100밀리초의 시간 제한이 있는 "majority" 쓰기 고려를 설정합니다.

try {
db.pizzas.bulkWrite( [
{ updateMany: {
filter: { size: "medium" },
update: { $inc: { price: 0.1 } }
} },
{ updateMany: {
filter: { size: "small" },
update: { $inc: { price: -0.25 } }
} },
{ deleteMany: { filter: { size: "large" } } },
{ insertOne: {
document: { _id: 4, type: "sausage", size: "small", price: 12 }
} } ],
{ writeConcern: { w: "majority", wtimeout: 100 } }
)
} catch( error ) {
print( error )
}

대부분의 복제본 세트 노드가 작업을 확인하는 데 걸리는 시간이 wtimeout을 초과하는 경우 이 예시에서는 쓰기 고려 오류와 완료된 작업의 요약이 반환됩니다.

result: BulkWriteResult {
result: {
ok: 1,
writeErrors: [],
writeConcernErrors: [
WriteConcernError {
err: {
code: 64,
codeName: 'WriteConcernFailed',
errmsg: 'waiting for replication timed out',
errInfo: { wtimeout: true, writeConcern: [Object] }
}
}
],
insertedIds: [ { index: 3, _id: 4 } ],
nInserted: 0,
nUpserted: 0,
nMatched: 2,
nModified: 2,
nRemoved: 0,
upserted: [],
opTime: { ts: Timestamp({ t: 1660329086, i: 2 }), t: Long("1") }
}
}
← db.collection.aggregate()

이 페이지의 내용