Operações de gravação em massa
Nesta página
- Visão geral
- Gravação em massa de collections
- Dados de amostra
- Inserir operações
- Atualizar operações
- Operações de substituição
- Excluir operações
- Executar a operação em massa
- Personalizar escrita em massa
- Valor de retorno
- Gravação em massa do cliente
- Inserir operações
- Atualizar operações
- Operações de substituição
- Executar a operação em massa
- Personalizar escrita em massa
- Informações adicionais
- Documentação da API
Visão geral
Este guia mostra como usar o driver Scala para executar uma operação de gravação em massa que faz várias alterações em seus dados em uma única chamada de banco de dados .
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 .
Gravação em massa de collections
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 Seq
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
Em seguida, passe uma lista dessas instâncias para o método bulkWrite()
.
As seções seguintes mostram como criar e utilizar instâncias das classes anteriores. A seção Executar a operação em massa demonstra como passar uma lista de modelos para o método bulkWrite()
para executar a operação em massa.
Dados de amostra
Os exemplos nesta seção utilizam a coleção do restaurants
no banco de dados do sample_restaurants
a partir do conjunto de dados de amostra do Atlas. Para acessar essa collection a partir do seu aplicação Scala, crie um MongoClient
que se conecte a um Atlas cluster e atribua os seguintes valores às suas variáveis database
e collection
:
val database: MongoDatabase = mongoClient.getDatabase("sample_restaurants") val collection: MongoCollection[Document] = database.getCollection("restaurants")
Para saber como criar um cluster MongoDB Atlas gratuito e carregar os conjuntos de dados de amostra, consulte o guia Iniciar com Atlas .
Inserir operações
Para executar uma operação de inserção, crie uma instância do InsertOneModel
e especifique o documento que você deseja inserir.
O exemplo a seguir cria uma instância de InsertOneModel
:
val insertOneModel = InsertOneModel( Document("name" -> "Blue Moon Grill", "borough" -> "Brooklyn", "cuisine" -> "American") )
Para inserir vários documentos, crie uma instância de InsertOneModel
para cada documento.
Importante
Ao executar uma operação em massa, o InsertOneModel
não pode inserir um documento com um _id
que já existe na coleção. Nessa situação, o driver lança um MongoBulkWriteException
.
Atualizar operações
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 saber mais sobre as 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
:
val updateOneFilter = equal("name", "White Horse Tavern") val updateOneDoc = set("borough", "Queens") val updateOneModel = UpdateOneModel(updateOneFilter, updateOneDoc)
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:
val options = UpdateOptions.sort(ascending("name"))
Para atualizar vários documentos, crie uma instância de UpdateManyModel
e passe os mesmos argumentos de UpdateOneModel
. A classe UpdateManyModel
especifica atualizações para todos os documentos que correspondem ao seu filtro de query.
O exemplo a seguir cria uma instância de UpdateManyModel
:
val updateManyFilter = equal("name", "Wendy's") val updateManyDoc = set("cuisine", "Fast food") val updateManyModel = UpdateManyModel(updateManyFilter, updateManyDoc)
Operações de substituição
Uma operação de substituição remove todos os campos e valores de um documento especificado e os substitui por novos campos e valores especificados por você. Para executar uma operação de substituição, crie uma instância de ReplaceOneModel
e passe os seguintes argumentos:
Filtro de query que especifica os critérios usados para corresponder aos documentos em sua coleção
documento de substituição que especifica os novos campos e valores a inserir
O exemplo a seguir cria uma instância de ReplaceOneModel
:
val replaceFilter = equal("name", "Cooper Town Diner") val replaceDoc = Document("name" -> "Smith Town Diner", "borough" -> "Brooklyn", "cuisine" -> "American") val replaceOneModel = ReplaceOneModel(replaceFilter, replaceDoc)
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:
val options = ReplaceOptions.sort(ascending("name"))
Dica
Substituir vários documentos
Para substituir vários documentos, crie uma instância de ReplaceOneModel
para cada documento.
Excluir operações
Para excluir um documento, crie uma instância de DeleteOneModel
e passe um filtro de query especificando o documento que deseja excluir. Uma instância do DeleteOneModel
fornece instruções para excluir somente o primeiro documento que corresponde ao seu filtro de query.
O exemplo a seguir cria uma instância de DeleteOneModel
:
val deleteOneModel = DeleteOneModel(equal("name", "Morris Park Bake Shop"))
Para excluir vários documentos, crie uma instância de DeleteManyModel
e passe um filtro de query especificando o documento que deseja excluir. Uma instância de DeleteManyModel
fornece instruções para remover todos os documentos que correspondem ao seu filtro de query.
O exemplo a seguir cria uma instância de DeleteManyModel
:
val deleteManyModel = DeleteManyModel(equal("cuisine", "Experimental"))
Executar a operação em massa
Depois de definir uma instância de modelo para cada operação que deseja executar, passe uma instância Seq
contendo os modelos para o método MongoCollection.bulkWrite()
. Por padrão, o método executa as operações na ordem especificada pela lista de modelos.
O exemplo a seguir executa diversas operações de gravação usando o método bulkWrite()
:
val insertOneModel = InsertOneModel( Document("name" -> "Red's Pizza", "borough" -> "Brooklyn", "cuisine" -> "Pizzeria") ) val updateOneModel = UpdateOneModel(equal("name", "Moonlit Tavern"), set("borough", "Queens")) val deleteManyModel = DeleteManyModel(equal("name", "Crepe")) val writes = Seq(insertOneModel, updateOneModel, deleteManyModel) val observable = collection.bulkWrite(writes) observable.subscribe( (result: BulkWriteResult) => println(s"Success: $result"), (error: Throwable) => println(s"Error: ${error.getMessage}"), () => println("Completed") )
Success: AcknowledgedBulkWriteResult{insertedCount=1, matchedCount=1, removedCount=1, modifiedCount=1, upserts=[], inserts=[BulkWriteInsert{index=0, id=BsonObjectId{value=...}}]} Completed
Se qualquer uma das operações de gravação falhar, o driver Scala emitirá um BulkWriteError
e não executará mais nenhuma operação. BulkWriteError
fornece um item details
que inclui a operação que falhou e detalhes sobre a exceção.
Observação
Quando o driver executa uma operação em massa, ele usa a preocupação de gravação da collection de destino. 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.
Personalizar escrita em massa
O método MongoCollection.bulkWrite()
aceita opcionalmente um parâmetro BulkWriteOptions
, que especifica as opções que você pode usar para configurar a operação de gravação em massa. Se você não especificar nenhuma opção, o driver executará a operação em massa com as configurações padrão. 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()
.
A tabela a seguir descreve os métodos de configuração que você pode usar para configurar uma instância BulkWriteOptions
:
Método | Descrição |
---|---|
| If true , the driver performs the write operations in the order
provided. If an error occurs, the remaining operations are not
attempted.If false , the driver performs the operations in an
arbitrary order and attempts to perform all operations.Defaults to true . |
| Specifies whether the update operation bypasses document validation. This lets you
update 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. Defaults to false . |
| Sets a comment to attach to the operation. |
| Provides a map of parameter names and values to set top-level
variables for the operation. Values must be constant or closed
expressions that don't reference document fields. |
O código a seguir cria opções e define a opção ordered
como false
para especificar uma escrita em massa não ordenada. Em seguida, o exemplo utiliza o método bulkWrite()
para executar uma operação em massa:
val options = BulkWriteOptions().ordered(false) val observable = collection.bulkWrite(writes, options)
Se qualquer uma das operações de escrita em uma escrita em massa não ordenada falhar, o driver Scala relatará os erros somente após tentar todas as operações.
Observação
Operações em massa não ordenadas não garantem uma ordem de execução. A ordem pode ser diferente da forma como você os lista para otimizar o tempo de execução.
Valor de retorno
O método bulkWrite()
retorna um objeto SingleObservable
que contém um BulkWriteResult
. Você pode acessar informações da instância BulkWriteResult
assinando o observable e usando os seguintes métodos:
Método | Descrição |
---|---|
| Indicates if the server acknowledged the write operation. |
| The number of documents deleted, if any. |
| The number of documents inserted, if any. |
| The list of inserted documents, if any. |
| The number of documents matched for an update, if applicable. |
| The number of documents modified, if any. |
| The list of upserted documents, if any. |
Gravação em massa do cliente
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 um List
contendo uma ou mais instâncias 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 ClientNamespacedInsertOneModel
representa uma operação para inserir um documento e você pode criar esse modelo usando o método ClientNamespacedWriteModel.insertOne()
.
A tabela a seguir descreve os modelos e seus métodos de instância correspondentes:
Modelo | Método de instância | Descrição | Parâmetros |
---|---|---|---|
|
| Cria um modelo para inserir um documento no |
|
|
| Cria um modelo para atualizar o primeiro documento no |
Você deve passar um valor para o parâmetro |
|
| Cria um modelo para atualizar todos os documentos no |
Você deve passar um valor para o parâmetro |
|
| Cria um modelo para substituir o primeiro documento no |
|
|
| Cria um modelo para excluir o primeiro documento no |
|
|
| Cria um modelo para excluir todos os documentos no |
|
As seções seguintes fornecem alguns exemplos de como criar modelos e utilizar o método do cliente bulkWrite()
.
Inserir operações
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.
val personToInsert = ClientNamespacedWriteModel.insertOne( MongoNamespace("db", "people"), Document("name" -> "Julia Smith") ) val thingToInsert = ClientNamespacedWriteModel.insertOne( MongoNamespace("db", "things"), Document("object" -> "washing machine") );
Atualizar operações
O exemplo seguinte mostra como utilizar o método bulkWrite()
para atualizar documentos existentes nas coleções db.people
e db.things
:
val personUpdate = ClientNamespacedWriteModel.updateOne( MongoNamespace("db", "people"), equal("name", "Freya Polk"), inc("age", 1) ) val thingUpdate = ClientNamespacedWriteModel.updateMany( MongoNamespace("db", "things"), equal("category", "electronic"), set("manufacturer", "Premium Technologies") )
Este exemplo incrementa o valor do campo age
por 1
no documento que tem um valor name
de "Freya Polk"
na coleção people
. Ele também define o valor do campo manufacturer
como "Premium Technologies"
em todos os documentos que têm um valor category
de "electronic"
na coleção things
.
Se vários documentos corresponderem ao filtro de query especificado em uma ClientNamespacedUpdateOneModel
instância do, a operação atualizará o primeiro resultado. Você pode especificar uma ordem de classificação em uma instância do ClientUpdateOneOptions para aplicar uma ordem aos documentos correspondentes antes que o driver execute a operação de atualização, conforme mostrado no código a seguir:
val options = ClientUpdateOneOptions .clientUpdateOneOptions() .sort(ascending("_id"))
Operações de substituição
O exemplo a seguir mostra como criar modelos para substituir documentos existentes nas coleções db.people
e db.things
:
val personReplacement = ClientNamespacedWriteModel.replaceOne( MongoNamespace("db", "people"), equal("_id", 1), Document("name" -> "Frederic Hilbert") ) val thingReplacement = ClientNamespacedWriteModel.replaceOne( MongoNamespace("db", "things"), equal("_id", 1), Document("object" -> "potato") )
O exemplo de código anterior substitui os seguintes documentos por novos documentos:
Documento na coleção
people
que tem um valor_id
de1
Documento na coleção
things
que tem um valor_id
de1
Se vários documentos corresponderem ao filtro de query especificado em uma ClientNamespacedReplaceOneModel
instância do, a operação substituirá o primeiro resultado. Você pode especificar uma ordem de classificação em uma instância do ClientReplaceOneOptions para aplicar uma ordem aos documentos correspondentes antes que o driver execute a operação de substituição, conforme mostrado no código a seguir:
val options = ClientReplaceOneOptions .clientReplaceOneOptions() .sort(ascending("_id"))
Executar a operação em massa
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 você as especifica.
O exemplo a seguir executa diversas operações de gravação usando o método bulkWrite()
:
val peopleNamespace = MongoNamespace("db", "people") val thingsNamespace = MongoNamespace("db", "things") val writeModels = List( ClientNamespacedWriteModel.insertOne( peopleNamespace, Document("name" -> "Corey Kopper") ), ClientNamespacedWriteModel.replaceOne( thingsNamespace, equal("_id", 1), Document("object" -> "potato") ) ) val observable = mongoClient.bulkWrite(writeModels) observable.subscribe( (result: ClientBulkWriteResult) => println(result.toString), (error: Throwable) => println(s"Error: ${error.getMessage}"), () => println("Completed") )
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 informações sobre a falha.
Personalizar escrita em massa
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.
Ordem de execução
Por padrão, o driver executa as operações individuais em uma operação em massa na ordem em que você as especifica. O driver executa as operações até que ocorra um erro ou até que a operação total em massa 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. Se você passar false
, o driver tentará executar todas as operações de gravação na operação de gravação em massa, mesmo que uma operação produza um erro.
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:
val namespace = MongoNamespace("db", "people") val options = ClientBulkWriteOptions.clientBulkWriteOptions().ordered(false) val writeModels = List( ClientNamespacedWriteModel.insertOne(namespace, Document("_id" -> 1, "name" -> "Rudra Suraj")), // Causes a duplicate key error ClientNamespacedWriteModel.insertOne(namespace, Document("_id" -> 1, "name" -> "Mario Bianchi")), ClientNamespacedWriteModel.insertOne(namespace, Document("name" -> "Wendy Zhang")) ) val observable = mongoClient.bulkWrite(writeModels, options)
Como a operação de gravação não é ordenada, o driver executa todas as operações sem erros, mesmo que a operação de gravação que insere um documento com uma chave duplicada resulte em um erro.
Informações adicionais
Para saber como realizar operações de escrita individuais, consulte os seguintes guias:
Documentação da API
Para saber mais sobre qualquer um dos métodos ou tipos discutidos neste guia, consulte a seguinte documentação da API:
Gravação em massa de collections
Gravação em massa do cliente