db.collection.bulkWrite()
MongoDB com drivers
Esta página documenta um método. Para ver o método equivalente em um driver MongoDB , consulte a página correspondente para sua linguagem de mongosh
programação:
Definição
db.collection.bulkWrite()
Executa múltiplas operações de gravação com controles para ordem de execução.
Retorna: - Um booleano
acknowledged
comotrue
se a operação foi executada com preocupação de gravação,ou sea preocupação de gravaçãofalse
foi desativada. - Uma contagem para cada operação de gravação.
- Uma array contendo um
_id
para cada documento inserido ou atualizado com sucesso.
- Um booleano
Compatibilidade
db.collection.bulkWrite()
está disponível em sistemas hospedados nos seguintes ambientes:
MongoDB Atlas: o serviço totalmente gerenciado para implantações do MongoDB na nuvem
Observação
Este comando é aceito em todos os clusters do MongoDB Atlas. Para obter informações sobre o suporte do Atlas a todos os comandos, consulte Comandos não suportados.
MongoDB Enterprise: a versão autogerenciada e baseada em assinatura do MongoDB
MongoDB Community: uma versão com código disponível, de uso gratuito e autogerenciada do MongoDB
Observação
Não é possível executar operações de gravação em massa na IU do Atlas . Para inserir vários documentos, você deve inserir uma array de documentos. Para saber mais, consulte Criar, exibir, atualizar e excluir documentos na documentação do Atlas.
Sintaxe
O método bulkWrite()
tem o seguinte formato:
db.collection.bulkWrite( [ <operation 1>, <operation 2>, ... ], { writeConcern : <document>, ordered : <boolean> } )
O método bulkWrite()
utiliza os seguintes parâmetros:
Parâmetro | Tipo | Descrição | ||
---|---|---|---|---|
| array | Uma array de Operações válidas: Consulte Operações de Escrita para uso de cada operação | ||
| documento | Opcional. Um documento que expressa o write concern. Omitir para usar o write concern padrão. Não defina explicitamente a preocupação de gravação para a operação se for executada em uma transação. Para usar write concern com transações, consulte Transações e write concern. | ||
| booleano | Opcional. Um booleano que especifica se a instância Consulte Execução de operações |
Comportamento
bulkWrite()
pega uma array de operações de gravação e executa todas elas. Por padrão, as operações são executadas em ordem. Consulte Execução de operações para saber como controlar a ordem de execução da operação de gravação.
Operações de Escrita
insertOne
Insere um único documento na coleção.
db.collection.bulkWrite( [ { insertOne : { "document" : <document> } } ] )
Consulte db.collection.insertOne()
.
updateOne e updateMany
updateOne
atualiza um único documento na coleção que corresponde ao filtro. Se vários documentos corresponderem, o updateOne
atualizará somente o primeiro documento correspondente.
db.collection.bulkWrite( [ { updateOne : { "filter": <document>, "update": <document or pipeline>, "upsert": <boolean>, "collation": <document>, "arrayFilters": [ <filterdocument1>, ... ], "hint": <document|string> } } ] )
updateMany
atualiza todos os documentos na coleção que correspondem ao filtro.
db.collection.bulkWrite( [ { updateMany : { "filter" : <document>, "update" : <document or pipeline>, "upsert" : <boolean>, "collation": <document>, "arrayFilters": [ <filterdocument1>, ... ], "hint": <document|string> } } ] )
Campo | Notas |
---|---|
| Os critérios de seleção para a atualização. Os mesmos seletores de consulta que no método |
| A operação de atualização para executar. Pode especificar:
|
| Opcional. Um booleano para indicar se deve ser realizado um upsert. Por padrão, |
| Opcional. Uma array de documentos de filtro que determina quais elementos da array modificar para uma operação de atualização em um campo da array. |
| Opcional. Especifica a agrupamento para utilizar para a operação. |
| Opcional. O índice para utilizar para suportar a atualização |
Para detalhes, consulte db.collection.updateOne()
e db.collection.updateMany()
.
replaceOne
replaceOne
substitui um documento único na coleção que corresponda ao filtro. Se vários documentos corresponderem, o replaceOne
substituirá o primeiro documento correspondente somente.
db.collection.bulkWrite([ { replaceOne : { "filter" : <document>, "replacement" : <document>, "upsert" : <boolean>, "collation": <document>, "hint": <document|string> } } ] )
Campo | Notas |
---|---|
| Os critérios de seleção para a operação de substituição. Os mesmos query selectors do método |
| O documento de substituição. O documento não pode conter operadores de atualização. |
| Opcional. Um booleano para indicar se deve ser realizado um upsert. Por padrão, |
| Opcional. Especifica a agrupamento para utilizar para a operação. |
| Opcional. O índice para utilizar para suportar a atualização |
Para detalhes, consulte db.collection.replaceOne()
.
deleteOne e deleteMany
deleteOne
exclui um único documento da coleção que corresponde ao filtro. Se vários documentos corresponderem, deleteOne
excluirá apenas o primeiro documento correspondente.
db.collection.bulkWrite([ { deleteOne : { "filter" : <document>, "collation" : <document> // Available starting in 3.4 } } ] )
deleteMany
exclui todos os documentos na coleção que correspondem ao filtro.
db.collection.bulkWrite([ { deleteMany: { "filter" : <document>, "collation" : <document> // Available starting in 3.4 } } ] )
Campo | Notas |
---|---|
| Os critérios de seleção para a operação de exclusão. Os mesmos seletores de query que no método |
| Opcional. Especifica a agrupamento para utilizar para a operação. |
Para detalhes, consulte db.collection.deleteOne()
e db.collection.deleteMany()
.
_id
Campo
Se o documento não especificar um campo _id, então mongod
adicionará o campo _id
e atribuirá um ObjectId()
exclusivo para o documento antes de inseri-lo ou exibi-lo. A maioria dos drivers cria um ObjectId e insere o campo _id
, mas o mongod
criará e preencherá o _id
se o driver ou aplicativo não.
Se o documento contiver um campo _id
, o valor _id
deverá ser único dentro da collection para evitar erro de chave duplicada.
A atualização ou substituição de operações não pode especificar um valor _id
que difere do documento original.
Execução de operações
O parâmetro ordered
especifica se bulkWrite()
executará as operações em ordem ou não. Por padrão, as operações são executadas em ordem.
O seguinte código representa um bulkWrite()
com cinco operações.
db.collection.bulkWrite( [ { insertOne : <document> }, { updateOne : <document> }, { updateMany : <document> }, { replaceOne : <document> }, { deleteOne : <document> }, { deleteMany : <document> } ] )
No estado ordered : true
padrão, cada operação será executada para, da primeira operação insertOne
para a última operação deleteMany
.
Se ordered
estiver definido como falsas, as operações poderão ser reordenadas por mongod
para aumentar o desempenho. Os aplicativos não devem depender da ordem de execução da operação.
O seguinte código representa um bulkWrite()
não ordenado com seis operações:
db.collection.bulkWrite( [ { insertOne : <document> }, { updateOne : <document> }, { updateMany : <document> }, { replaceOne : <document> }, { deleteOne : <document> }, { deleteMany : <document> } ], { ordered : false } )
Com o ordered : false
, os resultados da operação podem variar. Por exemplo, as operações deleteOne
ou deleteMany
podem remover mais ou menos documentos, dependendo do fato de serem executadas antes ou depois das operações insertOne
, updateOne
, updateMany
ou replaceOne
.
O número de operações em cada grupo não pode exceder o valor do maxWriteBatchSize do banco de dados. A partir do MongoDB 3,6, esse valor é 100,000
. Este valor é mostrado no campo hello.maxWriteBatchSize
.
Esse limite evita problemas com mensagens de erro superdimensionadas. Se um grupo exceder este limite, o driver do cliente dividirá o grupo em grupos menores com contagens menores ou iguais ao valor do limite. Por exemplo, com o valor de maxWriteBatchSize
de 100,000
, se a fila for composta por 200,000
operações, o driver criará 2 grupos, cada um com 100,000
operações.
Observação
O driver só divide o grupo em grupos menores ao usar a API de alto nível. Se estiver usando db.runCommand() diretamente (por exemplo, ao gravar um driver), o MongoDB lançará um erro ao tentar executar um lote de gravação que exceda o limite.
A partir do MongoDB 3.6, uma vez que o relatório de erros de um único lote fica muito grande, o MongoDB trunca todas as mensagens de erro restantes em uma string vazia. Atualmente, começa quando há pelo menos 2 mensagens de erro com tamanho total maior que 1MB
.
Os tamanhos e mecânicas de agrupamento são detalhes de desempenho interno e estão sujeitos a alterações em versões futuras.
A execução de uma lista de operações ordered
em uma collection fragmentada geralmente será mais lenta do que a execução de uma lista unordered
, já que, com uma lista ordenada, cada operação deve aguardar a conclusão da operação anterior.
Capped collections
As operações de gravação bulkWrite()
têm restrições quando utilizadas em uma coleção limitada.
updateOne
e updateMany
jogou um WriteError
se os critérios de update
aumentarem o tamanho do documento que está sendo modificado.
replaceOne
lança um WriteError
se o documento replacement
tiver um tamanho maior que o documento original.
deleteOne
e deleteMany
lança um WriteError
se usado em uma capped collection.
Coleções de Time Series
bulkWrite()
operações de gravação têm restrições quando usadas em uma coleção de séries temporais. Somente insertOne
pode ser usado em coleção de séries temporais. Todas as outras operações retornarão um WriteError
.
Error Handling
db.collection.bulkWrite()
gera uma exceção BulkWriteError
em erros. Consulte Tratamento de erros dentro de transações.
Excluindo os erros de preocupação de gravação, as operações ordenadas são interrompidas após um erro, enquanto as operações não ordenadas continuam a processar quaisquer operações de gravação restantes na fila, a menos que sejam executadas em uma transação. Consulte Tratamento de erros dentro de transações.
Os erros de write concern são exibidos no campo writeConcernErrors
, enquanto todos os outros erros são exibidos no campo writeErrors
. Se um erro for encontrado, o número de operações de gravação bem-sucedidas será exibido em vez dos valores _id
inseridos. Operações ordenadas exibem o único erro encontrado enquanto operações não ordenadas exibem cada erro em um array.
Erros de validação de esquema
Se sua coleção usa validação de esquema e tem validationAction
definido como error
, inserir um documento inválido ou atualizar um documento com valores inválidos gera um erro. As operações que precedem a operação inválida na matriz operations
são executadas e gravadas na coleção. O campo ordered
determina se as operações restantes são executadas.
Transações
db.collection.bulkWrite()
pode ser usado dentro de transações distribuídas.
Importante
Na maioria dos casos, uma transação distribuída incorre em um custo de desempenho maior do que as gravações de um único documento, e a disponibilidade de transações distribuídas não deve substituir o design eficaz do esquema. Em muitos cenários, o modelo de dados desnormalizado (documentos e arrays incorporados) continuará a ser ideal para seus dados e casos de uso. Ou seja, para muitos cenários, modelar seus dados adequadamente minimizará a necessidade de transações distribuídas.
Para considerações adicionais sobre o uso de transações (como limite de tempo de execução e limite de tamanho do oplog), consulte também Considerações de produção.
Inserções e inserções posteriores em transações
Para "4.4"
versão de compatibilidade de recurso
Observação
Você não pode criar uma nova coleta em transações de gravação entre fragmentos. Por exemplo, se você gravar em uma coleta existente em um fragmento e criar implicitamente uma coleta em um fragmento diferente, o MongoDB não poderá executar ambas as operações na mesma transação.
Write concerns e transações
Não defina explicitamente a preocupação de gravação para a operação se for executada em uma transação. Para usar write concern com transações, consulte Transações e write concern.
Tratamento de erros nas transações
A partir do MongoDB 4.2, se uma operação db.collection.bulkWrite()
encontrar um erro dentro de uma transação, o método lançará uma BulkWriteException (igual a uma transação externa).
Na 4.0, se a operação bulkWrite
encontrar um erro em uma transação, o erro lançado não será agrupado como um BulkWriteException
.
Em uma transação, o primeiro erro em uma gravação em massa faz com que toda a gravação em massa falhe e cancele a transação, mesmo que a gravação em massa não seja ordenada.
Exemplos
Exemplo de escrita em massa ordenada
É importante que você entenda bulkWrite()
ordem de operação e tratamento de erros. Por padrão, o bulkWrite()
executa uma lista ordenada de operações:
As operações são executadas em série.
Se uma operação tiver um erro, esta operação e quaisquer operações seguintes não serão executadas.
Operações listadas antes da operação de erro ser concluída.
Os exemplos de bulkWrite()
utilizam a coleção 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 } ] )
O seguinte exemplo do bulkWrite()
executa estas operações na coleção pizzas
:
Adiciona dois documentos usando
insertOne
.Atualiza um documento usando
updateOne
.Exclui um documento usando
deleteOne
.Substitui um documento usando
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 ) }
Exemplo de saída, que inclui um resumo das operações concluídas:
{ acknowledged: true, insertedCount: 2, insertedIds: { '0': 3, '1': 4 }, matchedCount: 2, modifiedCount: 2, deletedCount: 1, upsertedCount: 0, upsertedIds: {} }
Se a coleção já continha um documento com uma _id
de 4
antes de executar o bulkWrite()
anterior, a seguinte exceção de chave duplicada será retornada para a segunda operação 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: [] } }
Como o exemplo bulkWrite()
está ordenado, somente a primeira operação insertOne
é concluída.
Para concluir todas as operações que não tenham erros, execute bulkWrite()
com ordered
definido como false
. Para ver um exemplo, consulte a seção a seguir.
Exemplo de gravação em massa não solicitada
Para especificar um bulkWrite()
não ordenado, defina ordered
como false
.
Em uma lista bulkWrite()
não ordenada de operações:
As operações podem ser executadas em paralelo (não garantidas). Para detalhes. Consulte Operações ordenadas versus não ordenadas.
Operações com erros não estão concluídas.
Todas as operações sem erros estão concluídas.
Continuando com o exemplo da coleção pizzas
, descarte e recrie a coleção:
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 } ] )
No exemplo a seguir:
bulkWrite()
executa operações não ordenadas na coleçãopizzas
.A segunda operação
insertOne
tem o mesmo_id
da primeirainsertOne
, o que causa um erro de chave duplicada.
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 ) }
Exemplo de saída, que inclui o erro da chave duplicada e um resumo das operações concluídas:
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: [] } }
A segunda operação insertOne
falha devido ao erro de chave duplicada. Em um bulkWrite()
não ordenado, qualquer operação sem erro é concluída.
Exemplo de gravação em massa com write concern
Continuando com o exemplo da coleção pizzas
, descarte e recrie a coleção:
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 } ] )
O exemplo bulkWrite()
a seguir executa operações na pizzas
e define uma preocupação de gravação "majority"
com um tempo limite de 100 milésimos de segundo:
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 ) }
Se o tempo para que a maioria dos membros do conjunto de réplicas reconheça as operações exceder wtimeout
, o exemplo retornará um erro de write concern e um resumo das operações concluídas:
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") } } }