Operações de gravação em massa
Nesta página
Visão geral
O MongoDB oferece aos clientes a capacidade de realizar operações de gravação em massa. Operações de escrita em massa afetam uma coleção única. O MongoDB permite que os aplicativos determinem o nível aceitável de reconhecimento necessário para operações de escrita em massa.
Novo na versão 3.2.
O método db.collection.bulkWrite()
oferece a capacidade de realizar operações de inserção, atualização e exclusão em massa.
O MongoDB também suporta inserção em massa pelo método db.collection.insertMany()
.
Operações ordenadas versus não ordenadas
Operações de gravação em massa podem ser 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.Ver escrita em massa ordenada
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 escrita restantes na lista. Veja o exemplo de escrita em massa não ordenada.
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, o bulkWrite()
executa operações do ordered
. Para especificar unordered
operações de gravação, defina ordered : false
no documento de opções.
Consulte Execução de operações
bulkWrite() Methods
bulkWrite()
suporta as seguintes operações de gravação:
Cada operação de gravação é passada para bulkWrite()
como um documento em uma array.
Exemplo
O exemplo nesta seção utiliza 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 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 Exemplos de bulkWrite().
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 a collection fragmentada estiver vazia, ela terá apenas um chunk inicial, que reside em um único shard. Nesse caso, o MongoDB deverá dedicar algum tempo para receber dados, criar divisões e distribuir os chunks divididos para os shards disponíveis. Para evitar esse custo de desempenho, você pode pré-dividir a collection, conforme descrito em Dividir chunks em um cluster fragmentado.
Gravações não ordenadas em mongos
Para melhorar o desempenho de gravação em clusters fragmentados, use bulkWrite()
com o parâmetro opcional ordered
definido como false
. mongos
pode tentar enviar as gravações 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
Veja também:
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).