Visão geral
O MongoDB oferece aos clientes a capacidade de realizar operações de gravação em massa. A partir do MongoDB 8.0, você pode executar operações de gravação em massa em vários bancos de dados e collections. Se você estiver usando uma versão anterior ao MongoDB 8.0, poderá executar operações de gravação em massa em uma única coleção.
Para realizar operações de escrita em massa em vários bancos de dados e collections no MongoDB 8.0, use o comando de banco de dadosbulkWrite
ou o método Mongo.bulkWrite()
mongosh
.
Para executar operações de escrita em massa em uma única collection, use o método db.collection.bulkWrite()
mongosh
. Se você estiver executando o MongoDB 8.0 ou posterior, também poderá usar bulkWrite
ou Mongo.bulkWrite()
para escrever em uma única collection.
Operações ordenadas versus não ordenadas
Você pode definir suas operações de gravação em massa como ordenadas ou não ordenadas.
Com uma lista ordenada de operações, o MongoDB executa as operações serialmente. Se ocorrer um erro durante o processamento de uma das operações de gravação, o MongoDB retornará sem processar as operações de gravação restantes na lista.
Com uma lista não ordenada de operações, o MongoDB pode executar as operações em paralelo, mas esse comportamento não é garantido. Se ocorrer um erro durante o processamento de uma das operações de gravação, o MongoDB continuará processando as operações de gravação restantes na lista.
Em geral, a execução de uma lista ordenada de operações em uma coleção fragmentada será mais lenta do que a execução de uma lista não ordenada, pois com uma lista ordenada, cada operação deve aguardar a conclusão da operação anterior.
Por padrão, todos os comandos e métodos de gravação em massa executam operações ordenadas. Para especificar operações não ordenadas, defina a opção ordered
como false
ao chamar seu comando ou método preferido. Para saber mais sobre a sintaxe de cada comando ou método, consulte suas páginas vinculadas acima.
Métodos de gravação em massa
Todos os métodos e comandos de escrita em massa suportam as seguintes operações de escrita:
insertOne
UpdateOne
UpdateMany
replaceOne
Excluir um
deleteMany
Ao chamar seu comando ou método preferido, você passa cada operação de gravação como um documento em uma array. Para saber mais sobre a sintaxe de cada comando ou método, consulte suas páginas vinculadas acima.
Exemplo
db.collection.bulkWrite()
O seguinte db.collection.bulkWrite()
exemplo executa as seguintes operações na coleção do 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: {} }
Para obter mais exemplos, consulte db.collection.bulkWrite() Exemplos.
Mongo.bulkWrite()
Este exemplo usa Mongo.bulkWrite()
para executar as seguintes operações em ordem:
insere um documento na coleção
db.authors
insere um documento na coleção
db.books
atualiza o documento anterior
db.getMongo().bulkWrite( [ { namespace: 'db.authors', name: 'insertOne', document: { name: 'Stephen King' } }, { namespace: 'db.books', name: 'insertOne', document: { name: 'It' } }, { namespace: 'db.books', name: 'updateOne', filter: { name: 'it' }, update: { $set: { year: 1986 } } } ], { ordered: true, bypassDocumentValidation: true } )
mongosh
executa a gravação em massa para e retorna o seguinte documento:
{ acknowledged: true, insertedCount: 2, matchedCount: 1, modifiedCount: 1, deletedCount: 0, upsertedCount: 0, insertResults: { '1': { insertedId: ObjectId('67ed8ce8efd926c84cab7945') }, '2': { insertedId: ObjectId('67ed8ce8efd926c84cab7946') } } updateResults: { '1': { matchedCount: 1, modifiedCount: 1, didUpsert: false } } }
Estratégias para inserção em massa em uma coleção compartilhada
Grandes operações de inserção em massa, incluindo inserções iniciais de dados ou importação de dados de rotina, podem afetar o desempenho do cluster fragmentado. Para inserções em massa, considere as seguintes estratégias:
Pré-divisão da coleção
Se sua coleção fragmentada estiver vazia e você não estiver usando fragmentação com hash para a primeira chave da sua chave de fragmento, então sua coleção terá apenas um chunk inicial, que reside em um único fragmento. O MongoDB deve então dedicar tempo para receber dados e distribuir as partes para os fragmentos disponíveis. Para evitar esse custo de desempenho, pré-divida a coleção criando intervalos em um cluster fragmentado.
Gravações não ordenadas em mongos
Para melhorar o desempenho de gravação em clusters fragmentados, execute uma gravação em massa não ordenada definindo ordered
como false
quando você chamar seu método ou comando preferido. mongos
pode tentar enviar os escritos para vários fragmentos simultaneamente. Para coleções vazias, primeiro pré-dividir a coleção conforme descrito em Dividir partes em um cluster fragmentado.
Evite a aceleração monotônica
Se sua chave de estilhaço aumenta monotonicamente durante uma inserção, todos os dados inseridos vão para o último bloco da coleção, que sempre terminará em um único fragmento. Portanto, a capacidade de inserção do cluster nunca excederá a capacidade de inserção desse único fragmento.
Se o volume de inserção for maior do que o que um único estilhaço pode processar e se você não puder evitar uma chave de estilhaço monotonicamente crescente, considere as seguintes modificações no aplicativo:
Inverta os bits binários da chave de fragmento. Isso preserva as informações e evita correlacionar a ordem de inserção com a crescente sequência de valores.
Troque a primeira e a última palavras de 16 bits para "embaralhar" as inserções.
Exemplo
O exemplo a seguir, em C++, troca a palavra de 16 bits inicial e final dos BSON ObjectIds gerados para que eles não sejam mais monotonicamente crescentes.
using namespace mongo; OID make_an_id() { OID x = OID::gen(); const unsigned char *p = x.getData(); swap( (unsigned short&) p[0], (unsigned short&) p[10] ); return x; } void foo() { // create an object BSONObj o = BSON( "_id" << make_an_id() << "x" << 3 << "name" << "jane" ); // now we may insert o into a sharded collection }
Dica
Chaves fragmentadas para obter informações sobre como escolher uma chave fragmentada. Veja também Internos da chave de fragmento (em particular, Escolha uma chave de fragmento).