Menu Docs
Página inicial do Docs
/ / /
Driver de fluxos reativos do Java
/

Operações de gravação em massa

Nesta página

  • Visão geral
  • Dados de amostra
  • Gravação em massa de collections
  • Inserir operações
  • Atualizar operações
  • Operações de substituição
  • Excluir operações
  • Executar a operação em massa
  • Personalizar escrita em massa
  • Gravação em massa do cliente
  • Inserir operações
  • Operações de substituição
  • Executar a operação em massa
  • Personalizar escrita em massa
  • Informações adicionais
  • Documentação da API

Neste guia, você aprenderá a executar várias operações de gravação em uma única chamada de banco de dados de dados usando operações de gravação em massa.

Considere um cenário no qual você deseja inserir um documento, atualizar vários outros documentos e excluir um documento. Se você usar métodos individuais, cada operação exigirá sua própria chamada de banco de dados .

Ao usar uma operação de gravação em massa, você pode executar várias operações de gravação em menos chamadas de banco de dados . Você pode realizar operações de gravação em massa nos seguintes níveis:

  • Collection: você pode usar o MongoCollection.bulkWrite() método para realizar operações de escrita em massa em uma única collection. Nesse método, cada tipo de operação de gravação requer pelo menos uma chamada de banco de dados . Por exemplo, MongoCollection.bulkWrite() coloca várias operações de atualização em uma chamada, mas faz duas chamadas separadas para o banco de dados para uma operação de inserção e uma operação de substituição.

  • Cliente: se o seu aplicação se conectar ao MongoDB Server versão 8.0 ou posterior, você poderá usar o MongoClient.bulkWrite() método para executar operações de gravação em massa em várias collections e bancos de dados no mesmo cluster. Este método executa todas as operações de gravação em uma chamada de banco de dados .

Os exemplos neste guia usam a sample_restaurants.restaurants collection dos conjuntos de dados de amostra do Atlas . Para aprender como criar um agrupamento MongoDB Atlas gratuito e carregar os conjuntos de dados de amostra, consulte o tutorialde Introdução do.

Importante

Biblioteca do Reator do Projeto

Este guia usa a biblioteca Project Reactor para consumir Publisher instâncias do retornadas pelos métodos de driver Java Reactive Streams. Para saber mais sobre a biblioteca do Projeto Reactor e como usá-la, consulte Introdução na documentação do Reactor. Para saber mais sobre como usamos os métodos da biblioteca do Project Reactor neste guia, consulte o guia Gravar dados no MongoDB .

As operações de gravação em massa contêm uma ou mais operações de gravação. Para executar uma operação de gravação em massa no nível da coleção, passe um List de WriteModel documentos para o método MongoCollection.bulkWrite(). Um WriteModel é um modelo que representa uma operação de gravação.

Para cada operação de gravação que você deseja executar, crie uma instância de uma das seguintes classes que herdam de WriteModel:

  • InsertOneModel

  • UpdateOneModel

  • UpdateManyModel

  • ReplaceOneModel

  • DeleteOneModel

  • DeleteManyModel

As seções seguintes mostram como criar e utilizar instâncias das classes anteriores.

Para executar uma operação de inserção, crie uma instância de InsertOneModel e passe no documento que você deseja inserir.

O exemplo a seguir cria uma instância de InsertOneModel:

InsertOneModel<Document> operation = new InsertOneModel<>(
new Document("name", "Mongo's Deli")
.append("cuisine", "Sandwiches"));

Para inserir vários documentos, crie uma instância de InsertOneModel para cada documento.

Para atualizar um documento, crie uma instância de UpdateOneModel e passe os seguintes argumentos:

  • Filtro de query que especifica os critérios usados para corresponder aos documentos em sua coleção.

  • Atualize a operação que você deseja executar. Para obter mais informações sobre operações de atualização, consulte o guia Operadores de atualização de campo no manual do MongoDB Server .

O exemplo a seguir cria uma instância de UpdateOneModel:

UpdateOneModel<Document> operation = new UpdateOneModel<>(
eq("name", "Mongo's Deli"),
set("cuisine", "Sandwiches and Salads"));

Se vários documentos corresponderem ao filtro de query especificado na instância UpdateOneModel, a operação atualizará o primeiro resultado. Você pode especificar uma classificação em uma instância do UpdateOptions para aplicar um pedido aos documentos correspondentes antes que o driver execute a operação de atualização, conforme mostrado no código a seguir:

UpdateOptions options = UpdateOptions.sort(Sorts.ascending("_id"));

Para atualizar vários documentos, crie uma instância de UpdateManyModel e passe os mesmos argumentos. UpdateManyModel atualiza todos os documentos que correspondem ao seu filtro de query.

O exemplo a seguir cria uma instância de UpdateManyModel:

UpdateManyModel<Document> operation = new UpdateManyModel<>(
eq("name", "Mongo's Deli"),
set("cuisine", "Sandwiches and Salads"));

Uma operação de substituição remove todos os campos e valores de um documento especificado, exceto o campo _id , e os substitui por novos. Para executar uma operação de substituição, crie uma instância de ReplaceOneModel e passe um filtro de query e os campos e valores que você deseja armazenar no documento correspondente.

O exemplo a seguir cria uma instância de ReplaceOneModel:

ReplaceOneModel<Document> operation = new ReplaceOneModel<>(
eq("name", "Original Pizza"),
new Document("name", "Mongo's Pizza")
.append("borough", "Manhattan"));

Se vários documentos corresponderem ao filtro de query especificado na instância ReplaceOneModel, a operação substituirá o primeiro resultado. Você pode especificar uma classificação em uma instância do ReplaceOptions para aplicar um pedido aos documentos correspondentes antes que o driver execute a operação de substituição, conforme mostrado no código a seguir:

ReplaceOptions options = ReplaceOptions.sort(Sorts.ascending("_id"));

Dica

Substituir vários documentos

Para substituir vários documentos, crie uma instância de ReplaceOneModel para cada documento.

Para excluir um documento, crie uma instância do DeleteOneModel e passe um filtro de query especificando o documento que você deseja excluir. DeleteOneModel remove somente o primeiro documento que corresponde ao seu filtro de query.

O exemplo a seguir cria uma instância de DeleteOneModel:

DeleteOneModel<Document> operation = new DeleteOneModel<>(
eq("restaurant_id", "5678"));

Para excluir vários documentos, crie uma instância do DeleteManyModel e passe um filtro de query especificando os documentos que deseja excluir. DeleteManyModel remove todos os documentos que correspondem ao seu filtro de query.

O exemplo a seguir cria uma instância de DeleteManyModel:

DeleteManyModel<Document> operation = new DeleteManyModel<>(
eq("name", "Mongo's Deli"));

Depois de definir uma instância WriteModel para cada operação que deseja executar, passe uma lista dessas instâncias para o método bulkWrite(). Por padrão, o método executa as operações na ordem em que foram definidas na lista.

O exemplo a seguir executa diversas operações de gravação usando o método bulkWrite() :

Publisher<BulkWriteResult> bulkWritePublisher = restaurants.bulkWrite(
Arrays.asList(new InsertOneModel<>(
new Document("name", "Mongo's Deli")
.append("cuisine", "Sandwiches")
.append("borough", "Manhattan")
.append("restaurant_id", "1234")),
new InsertOneModel<>(new Document("name", "Mongo's Deli")
.append("cuisine", "Sandwiches")
.append("borough", "Brooklyn")
.append("restaurant_id", "5678")),
new UpdateManyModel<>(eq("name", "Mongo's Deli"),
set("cuisine", "Sandwiches and Salads")),
new DeleteOneModel<>(eq("restaurant_id", "1234"))));
BulkWriteResult bulkResult = Mono.from(bulkWritePublisher).block();
System.out.println(bulkResult.toString());
AcknowledgedBulkWriteResult{insertedCount=2, matchedCount=2, removedCount=1, modifiedCount=2, upserts=[], inserts=[BulkWriteInsert{index=0, id=BsonObjectId{value=66a7e0a6c08025218b657208}}, BulkWriteInsert{index=1, id=BsonObjectId{value=66a7e0a6c08025218b657209}}]}

Se qualquer uma das operações de gravação falhar, o driver Java Reactive Streams sinalizará um MongoBulkWriteException e não executará mais nenhuma operação individual. MongoBulkWriteException inclui um BulkWriteError que pode ser acessado usando o método MongoBulkWriteException.getWriteErrors() , que fornece detalhes da falha individual.

Observação

Quando o driver Java Reactive Streams executa uma operação em massa, ele usa o writeConcern da collection na qual a operação está sendo executada. O driver relata todos os erros de preocupação de gravação depois de tentar todas as operações, independentemente da ordem de execução.

A classe BulkWriteOptions contém métodos que modificam o comportamento do método bulkWrite() . Para usar a classe BulkWriteOptions , construa uma nova instância da classe e, em seguida, chame um ou mais de seus métodos para modificar a operação de gravação. Você pode encadear essas chamadas de método. Para modificar o comportamento da operação de gravação, passe a instância da classe como o último argumento para o método bulkWrite() .

Você pode utilizar os seguintes métodos na classe BulkWriteOptions para modificar um método de escrita. Todos os métodos são opcionais.

Método
Descrição

bypassDocumentValidation(Boolean bypassDocumentValidation)

Specifies whether the bulk write operation bypasses document validation. This lets you perform write operations on documents that don't meet the schema validation requirements, if any exist. For more information about schema validation, see Schema Validation in the MongoDB Server manual.

comment(Bson comment)

Attaches a Bson comment to the operation. For more information, see the insert command fields guide in the MongoDB Server manual.

comment(String comment)

Attaches a String comment to the operation. For more information, see the insert command fields guide in the MongoDB Server manual.

let(Bson variables)

Specifies a map of parameter names and values. Values must be constant or closed expressions that don't reference document fields. For more information, see the let statement in the MongoDB Server manual.

ordered(Boolean ordered)

If set to True, the driver performs the individual operations in the order provided. If an individual operation fails, the driver will not execute any subsequent individual operations.
Defaults to True.

O exemplo a seguir chama o método bulkWrite() do exemplo anterior, mas define a opção ordered como False:

Publisher<BulkWriteResult> bulkWritePublisher = restaurants.bulkWrite(
Arrays.asList(new InsertOneModel<>(
new Document("name", "Mongo's Deli")
.append("cuisine", "Sandwiches")
.append("borough", "Manhattan")
.append("restaurant_id", "1234")),
new InsertOneModel<>(new Document("name", "Mongo's Deli")
.append("cuisine", "Sandwiches")
.append("borough", "Brooklyn")
.append("restaurant_id", "5678")),
new UpdateManyModel<>(eq("name", "Mongo's Deli"),
set("cuisine", "Sandwiches and Salads")),
new DeleteOneModel<>(eq("restaurant_id", "1234"))),
new BulkWriteOptions().ordered(false));
BulkWriteResult bulkResult = Mono.from(bulkWritePublisher).block();
System.out.println(bulkResult.toString());
AcknowledgedBulkWriteResult{insertedCount=2, matchedCount=2, removedCount=1, modifiedCount=2, upserts=[], inserts=[BulkWriteInsert{index=0, id=BsonObjectId{value=66a7e03cce430c5854b6caf9}}, BulkWriteInsert{index=1, id=BsonObjectId{value=66a7e03cce430c5854b6cafa}}]}

Se qualquer uma das operações de gravação em uma gravação em massa não ordenada falhar, o driver Java Reactive Streams relatará os erros somente depois de tentar todas as operações.

Observação

Operações em massa não ordenadas não garantem ordem de execução. A ordem pode ser diferente da forma como você os lista para otimizar o tempo de execução.

Ao conectar a um sistema executando o MongoDB Server 8.0 ou posterior, você pode usar o método MongoClient.bulkWrite() para escrever em vários bancos de dados e collections no mesmo cluster. O método MongoClient.bulkWrite() executa todas as operações de gravação em uma única chamada.

O método MongoClient.bulkWrite() usa uma lista de instâncias do ClientNamespacedWriteModel para representar diferentes operações de gravação. Você pode construir instâncias da interface ClientNamespacedWriteModel utilizando métodos de instância. Por exemplo, uma instância de ClientNamespacedInsertOneModel representa uma operação para inserir um documento e você pode criar esse modelo usando o método ClientNamespacedWriteModel.insertOne().

Os modelos e seus métodos de instância correspondentes são descritos na tabela abaixo.

Modelo
Método de instância
Descrição
Parâmetros

ClientNamespacedInsertOneModel

insertOne()

Cria um modelo para inserir um documento no namespace.

namespace: Banco de dados e coleção para escrever em

document: Documento a inserir

ClientNamespacedUpdateOneModel

updateOne()

Cria um modelo para atualizar o primeiro documento no namespace que corresponde a filter.

namespace: Banco de dados e coleção para escrever em

filter: Filtro que seleciona qual documento atualizar

update: Atualize para aplicar ao documento correspondente

updatePipeline: Atualize o pipeline para aplicar ao documento correspondente

options: (opcional) Opções a serem aplicadas ao atualizar o documento

Você deve passar um valor para o parâmetro update ou updatePipeline.

ClientNamespacedUpdateManyModel

updateMany()

Cria um modelo para atualizar todos os documentos no namespace que correspondem a filter.

namespace: Banco de dados e coleção para escrever em

filter: Filtro que seleciona quais documentos atualizar

update: Atualize para aplicar aos documentos correspondentes

updatePipeline: Atualize o pipeline para aplicar aos documentos correspondentes

options: (opcional) Opções a serem aplicadas ao atualizar documentos

Você deve passar um valor para o parâmetro update ou updatePipeline.

ClientNamespacedReplaceOneModel

replaceOne()

Cria um modelo para substituir o primeiro documento no namespace que corresponde a filter.

namespace: Banco de dados e coleção para escrever em

filter: Filtro que seleciona qual documento substituir

replacement: documento de substituição

options: (opcional) Opções a serem aplicadas ao substituir documentos

ClientNamespacedDeleteOneModel

deleteOne()

Cria um modelo para excluir o primeiro documento no namespace que corresponde a filter.

namespace: Banco de dados e coleção para escrever em

filter: Filtro que seleciona qual documento excluir

option: (opcional) Opções a serem aplicadas ao excluir o documento

ClientNamespacedDeleteManyModel

deleteMany()

Cria um modelo para excluir todos os documentos no namespace que correspondem a filter.

namespace: Banco de dados e coleção para escrever em

filter: Filtro que seleciona quais documentos excluir

option: (opcional) Opções a serem aplicadas ao excluir documentos

As seções seguintes fornecem alguns exemplos de como criar modelos e utilizar o método do cliente bulkWrite().

Este exemplo mostra como criar modelos que contêm instruções para inserir dois documentos. Um documento é inserido na collection db.people e o outro documento é inserido na collection db.things. A instância MongoNamespace define o banco de dados de destino e a collection à qual cada operação de gravação se aplica.

ClientNamespacedInsertOneModel personToInsert = ClientNamespacedWriteModel
.insertOne(
new MongoNamespace("db", "people"),
new Document("name", "Julia Smith")
);
ClientNamespacedInsertOneModel thingToInsert = ClientNamespacedWriteModel
.insertOne(
new MongoNamespace("db", "things"),
new Document("object", "washing machine")
);

O exemplo a seguir mostra como criar modelos para substituir documentos existentes nas coleções db.people e db.things:

ClientNamespacedReplaceOneModel personReplacement = ClientNamespacedWriteModel
.replaceOne(
new MongoNamespace("db", "people"),
Filters.eq("_id", 1),
new Document("name", "Frederic Hilbert")
);
ClientNamespacedReplaceOneModel thingReplacement = ClientNamespacedWriteModel
.replaceOne(
new MongoNamespace("db", "things"),
Filters.eq("_id", 1),
new Document("object", "potato")
);

Depois que esse exemplo for executado com êxito, o documento que tem um valor _id de 1 na coleção people é substituído por um novo documento. O documento na coleção things que tem um valor _id de 1 é substituído por um novo documento.

Depois de definir uma instância ClientNamespacedWriteModel para cada operação que deseja executar, passe uma lista dessas instâncias para o método bulkWrite() do cliente . Por padrão, o método executa as operações na ordem em que são especificadas.

O exemplo a seguir executa diversas operações de gravação usando o método bulkWrite() :

MongoNamespace peopleNamespace = new MongoNamespace("db", "people");
MongoNamespace thingsNamespace = new MongoNamespace("db", "things");
List<ClientNamespacedWriteModel> bulkOperations = Arrays.asList(
ClientNamespacedWriteModel
.insertOne(
peopleNamespace,
new Document("name", "Corey Kopper")
),
ClientNamespacedWriteModel
.replaceOne(
thingsNamespace,
Filters.eq("_id", 1),
new Document("object", "potato")
)
);
Publisher<ClientBulkWriteResult> bulkWritePublisher = mongoClient
.bulkWrite(bulkOperations);
ClientBulkWriteResult clientBulkResult = Mono
.from(bulkWritePublisher)
.block();
System.out.println(clientBulkResult.toString());
AcknowledgedSummaryClientBulkWriteResult{insertedCount=1, matchedCount=1, ...}

Se qualquer uma das operações de gravação falhar, o driver emitirá um ClientBulkWriteException e não executará mais nenhuma operação individual. ClientBulkWriteException inclui um BulkWriteError que pode ser acessado usando o método ClientBulkWriteException.getWriteErrors() , que fornece detalhes da falha individual.

Você pode passar uma instância de ClientBulkWriteOptions para o método bulkWrite() para personalizar como o driver executa a operação de gravação em massa.

Por padrão, o driver executa as operações individuais em uma operação em massa na ordem em que você as especifica até que ocorra um erro ou até que a operação seja concluída com êxito.

No entanto, você pode passar false para o método ordered() ao criar uma instância do ClientBulkWriteOptions para direcionar o driver a executar operações de gravação de forma não ordenada. Ao usar a opção não ordenada, uma operação de produção de erro não impede que o driver execute outras operações de gravação na operação de gravação em massa.

O código a seguir define a opção ordered como false em uma instância de ClientBulkWriteOptions e executa uma operação de gravação em massa para inserir vários documentos.

MongoNamespace namespace = new MongoNamespace("db", "people");
ClientBulkWriteOptions options = ClientBulkWriteOptions
.clientBulkWriteOptions()
.ordered(false);
List<ClientNamespacedWriteModel> bulkOperations = Arrays.asList(
ClientNamespacedWriteModel.insertOne(
namespace,
new Document("_id", 1).append("name", "Rudra Suraj")
),
// Causes a duplicate key error
ClientNamespacedWriteModel.insertOne(
namespace,
new Document("_id", 1).append("name", "Mario Bianchi")
),
ClientNamespacedWriteModel.insertOne(
namespace,
new Document("name", "Wendy Zhang")
)
);
Publisher<ClientBulkWriteResult> bulkWritePublisher = mongoClient
.bulkWrite(bulkOperations, options);

Embora a operação de gravação que insere um documento com uma chave duplicada resulte em um erro, as outras operações são executadas porque a operação de gravação não é ordenada.

Para saber como realizar operações de escrita individuais, consulte os seguintes guias:

Para saber mais sobre qualquer um dos métodos ou tipos discutidos neste guia, consulte a seguinte documentação da API:

Voltar

Excluir