Menu Docs

Página inicial do DocsDesenvolver aplicaçõesManual do MongoDB

Operações de gravação em massa

Nesta página

  • Visão geral
  • Operações ordenadas versus não ordenadas
  • Métodos bulkWrite()
  • Exemplo
  • Estratégias para inserção em massa em uma coleção compartilhada

O MongoDB oferece aos clientes a capacidade de realizar operações de gravação em massa. Operações de gravação em massa afetam uma única coleção. O MongoDB permite que os aplicativos determinem o nível aceitável de confirmação necessário para operações de gravação em massa.

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 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() suporta as seguintes operações de gravação:

Cada operação de gravação é passada para bulkWrite() como um documento em uma array.

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().

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:

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.

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.

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).

← Excluir métodos