Menu Docs
Página inicial do Docs
/ / /
Driver Rust
/ / /

Operações em massa

Nesta página

  • Visão geral
  • Dados de amostra
  • Tipos de operação em massa
  • Insert
  • Substituir
  • Update
  • Excluir
  • Tipo de devolução
  • Modificar comportamento
  • Exemplo
  • Escrever em namespaces mistos
  • Informações adicionais

Neste guia, você verá como usar o driver Rust para executar operações em massa.

As operações em massa executam múltiplas operações de gravação em um ou mais namespaces. Um namespace é uma combinação do nome do banco de dados de dados e do nome da coleção, no formato <database>.<collection>. Como você executa operações em massa em uma instância do Client , você pode executar operações em massa em qualquer namespace no cluster acessado pelo seu cliente.

Você pode executar operações em massa para reduzir o número de chamadas para o servidor. Em vez de enviar uma solicitação para cada operação, as operações em massa executam várias operações em uma ação.

Este guia inclui as seguintes seções:

  • Dados de amostra apresentam os dados de amostra que são usados pelos exemplos de operação em massa

  • Tipos de operação em massa descreve como utilizar tipos de WriteModel para executar operações de inserção, substituição, atualização e exclusão em massa

  • Tipo de Retorno descreve o valor de retorno do método bulk_write() e como acessar informações sobre a operação em massa

  • Modificar Comportamento descreve como modificar o comportamento padrão do método bulk_write()

  • Gravar em namespaces mistos descreve como realizar uma operação em massa em vários namespaces em uma chamada de método

  • Informações adicionais fornecem links para recursos e documentação da API para os tipos e métodos mencionados neste guia

Importante

Para realizar operações de escrita em massa, certifique-se de que seu aplicação atenda aos seguintes requisitos:

  • Você está conectado à versão 8.0 do MongoDB Server ou posterior.

  • Você estiver usando o driver Rust versão 3.0 ou posterior.

Os exemplos deste guia usam os seguintes documentos de exemplo, que são armazenados na collection mushrooms no banco de dados de dados db :

let docs = vec![
doc! {"name" : "portobello", "color" : "brown", "edible" : true },
doc! {"name" : "chanterelle", "color" : "yellow", "edible" : true },
doc! {"name" : "oyster", "color" : "white", "edible" : true },
doc! {"name" : "fly agaric", "color" : "red", "edible" : false },
];

Você também pode usar tipos de estrutura personalizados para representar seus dados de amostra. Para obter um exemplo que executa uma operação em massa usando Mushroom estruturas para modelar os mesmos dados, consulte o exemplo de inserção de estruturas nesta página.

Para executar uma operação de gravação em massa, passe uma array de WriteModel instâncias de enumeração para o método bulk_write() .

Nesta seção, você aprenderá a executar as seguintes operações de escrita em massa definindo seus tipos WriteModel correspondentes:

Dica

Você também pode executar vários tipos de operações de gravação em uma única chamada de método bulk_write() . Para visualizar um exemplo que passa um UpdateOneModel e um InsertOneModel para a mesma chamada bulk_write() , consulte o exemplo Modificar comportamento neste guia.

Para executar uma operação de inserção em massa, crie uma instância InsertOneModel para cada documento que você deseja inserir. Em seguida, passe uma lista de modelos para o método bulk_write() .

A tabela a seguir descreve InsertOneModel campos que você pode definir chamando seus métodos construtores correspondentes:

Campo
Descrição
namespace
The namespace on which the insert is performed.
Type: Namespace
document
The document to insert.
Type: Document

Este exemplo executa as seguintes ações:

  • Especifica duas instâncias do InsertOneModel em uma array. Cada InsertOneModel representa um documento a ser inserido no namespace db.mushrooms .

  • Passa a array de modelos para o método bulk_write() .

  • Imprime o número de documentos inseridos.

let mushrooms: Collection<Document> = client.database("db").collection("mushrooms");
let models = vec![
InsertOneModel::builder()
.namespace(mushrooms.namespace())
.document(doc! {
"name": "lion's mane",
"color": "white",
"edible": true
})
.build(),
InsertOneModel::builder()
.namespace(mushrooms.namespace())
.document(doc! {
"name": "angel wing",
"color": "white",
"edible": false
})
.build(),
];
let result = client.bulk_write(models).await?;
println!("Inserted documents: {}", result.inserted_count);
Inserted documents: 2

Você também pode modelar seus documentos usando structs e inserir instâncias de struct em massa no namespace db.mushrooms .

Este exemplo executa a mesma operação que o exemplo de inserção de documentos anterior, mas insere instâncias do seguinte tipo de estrutura Mushroom :

#[derive(Serialize)]
struct Mushroom {
name: String,
color: String,
edible: bool,
}

O código a seguir usa o método insert_one_model() para construir uma instância InsertOneModel a partir de cada instância Mushroom e, em seguida, insere ambos os modelos em uma operação em massa:

let mushrooms: Collection<Mushroom> = client.database("db").collection("mushrooms");
let lions_mane = Mushroom {
name: "lion's mane".to_string(),
color: "white".to_string(),
edible: true,
};
let angel_wing = Mushroom {
name: "angel wing".to_string(),
color: "white".to_string(),
edible: false,
};
let lions_mane_model = mushrooms.insert_one_model(lions_mane)?;
let angel_wing_model = mushrooms.insert_one_model(angel_wing)?;
let result = client.bulk_write([lions_mane_model, angel_wing_model]).await?;
println!("Inserted documents: {}", result.inserted_count);
Inserted documents: 2

Dica

Para saber mais sobre tipos de estrutura personalizada e serialização no driver Rust, consulte o guia sobre Modelagem e serialização de dados.

Para executar uma operação de substituição em massa, crie uma instância ReplaceOneModel para cada documento que deseja substituir. Em seguida, passe uma lista de modelos para o método bulk_write() .

A tabela a seguir descreve ReplaceOneModel campos que você pode definir chamando seus métodos construtores correspondentes:

Campo
Descrição
namespace
The namespace on which the operation is performed.
Type: Namespace
filter
The filter that matches the document you want to replace.
Type: Document
replacement
The replacement document.
Type: Document
collation
(Optional) The collation to use when sorting results. To learn more about collations, see the Collations guide.
Type: Document
hint
(Optional) The index to use for the operation. To learn more about indexes, see the Indexes guide.
Type: Bson
upsert
(Optional) Whether a new document is created if no document matches the filter.
By default, this field is set to false.
Type: bool

Este exemplo executa as seguintes ações:

  • Especifica duas instâncias do ReplaceOneModel em uma array. As instâncias ReplaceOneModel contêm instruções para substituir documentos que representam Cogumelos no namespace db.mushrooms .

  • Passa a array de modelos para o método bulk_write() .

  • Imprime o número de documentos modificados.

let mushrooms: Collection<Document> = client.database("db").collection("mushrooms");
let models = vec![
ReplaceOneModel::builder()
.namespace(mushrooms.namespace())
.filter(doc! { "name": "portobello" })
.replacement(doc! {
"name": "cremini",
"color": "brown",
"edible": true
})
.build(),
ReplaceOneModel::builder()
.namespace(mushrooms.namespace())
.filter(doc! { "name": "oyster" })
.replacement(doc! {
"name": "golden oyster",
"color": "yellow",
"edible": true
})
.upsert(true)
.build(),
];
let result = client.bulk_write(models).await?;
println!("Modified documents: {}", result.modified_count);
Modified documents: 2

Para executar uma operação de atualização em massa, crie uma instância UpdateOneModel ou UpdateManyModel para cada atualização que você deseja fazer. Em seguida, passe uma lista de modelos para o método bulk_write() . Um UpdateOneModel atualiza somente um documento que corresponde a um filtro, enquanto um UpdateManyModel atualiza todos os documentos que correspondem a um filtro.

A tabela seguinte descreve os campos UpdateOneModel e UpdateManyModel que você pode definir chamando seus métodos construtor correspondentes:

Campo
Descrição
namespace
The namespace on which the operation is performed.
Type: Namespace
filter
The filter that matches one or more documents you want to update. When specified in an UpdateOneModel, only the first matching document will be updated. When specified in an UpdateManyModel, all matching documents will be updated.
Type: Document
update
The update to perform.
Type: UpdateModifications
array_filters
(Optional) A set of filters specifying which array elements an update applies to if you are updating an array-valued field.
Type: Array
collation
(Optional) The collation to use when sorting results. To learn more about collations, see the Collations guide.
Type: Document
hint
(Optional) The index to use for the operation. To learn more about indexes, see the Indexes guide.
Type: Bson
upsert
(Optional) Whether a new document is created if no document matches the filter. By default, this field is set to false.
Type: bool

Este exemplo executa as seguintes ações:

  • Especifica uma instância UpdateOneModel e uma instância UpdateManyModel em uma array. Esses modelos contêm instruções para atualizar documentos representando Cogumelos no namespace db.mushrooms .

  • Passa a array de modelos para o método bulk_write() .

  • Imprime o número de documentos modificados.

let mushrooms: Collection<Document> = client.database("db").collection("mushrooms");
let models = vec![
WriteModel::UpdateOne(
UpdateOneModel::builder()
.namespace(mushrooms.namespace())
.filter(doc! { "name": "fly agaric" })
.update(doc! { "$set": { "name": "fly amanita" } })
.upsert(true)
.build(),
),
WriteModel::UpdateMany(
UpdateManyModel::builder()
.namespace(mushrooms.namespace())
.filter(doc! { "color": "yellow" })
.update(doc! { "$set": { "color": "yellow/orange" } })
.build(),
),
];
let result = client.bulk_write(models).await?;
println!("Modified documents: {}", result.modified_count);
Modified documents: 2

Para executar uma operação de exclusão em massa, crie uma instância DeleteOneModel ou DeleteManyModel para cada operação de exclusão. Em seguida, passe uma lista de modelos para o método bulk_write() . Um DeleteOneModel exclui apenas um documento que corresponde a um filtro, enquanto um DeleteManyModel exclui todos os documentos que correspondem a um filtro.

A tabela seguinte descreve os campos DeleteOneModel e DeleteManyModel que você pode definir chamando seus métodos construtor correspondentes:

Campo
Descrição
namespace
The namespace on which the operation is performed.
Type: Namespace
filter
The filter that matches one or more documents you want to delete. When specified in a DeleteOneModel, only the first matching document will be deleted. When specified in a DeleteManyModel, all matching documents will be deleted.
Type: Document
collation
(Optional) The collation to use when sorting results. To learn more about collations, see the Collations guide.
Type: Document
hint
(Optional) The index to use for the operation. To learn more about indexes, see the Indexes guide.
Type: Bson

Este exemplo executa as seguintes ações:

  • Especifica uma instância DeleteOneModel e uma instância DeleteManyModel em uma array. Esses modelos contêm instruções para excluir documentos que representam Cogumelos no namespace db.mushrooms .

  • Passa a array de modelos para o método bulk_write() .

  • Imprime o número de documentos excluídos.

let mushrooms: Collection<Document> = client.database("db").collection("mushrooms");
let models = vec![
WriteModel::DeleteOne(
DeleteOneModel::builder()
.namespace(mushrooms.namespace())
.filter(doc! { "color": "red" })
.build(),
),
WriteModel::DeleteMany(
DeleteManyModel::builder()
.namespace(mushrooms.namespace())
.filter(doc! { "edible": true })
.build(),
),
];
let result = client.bulk_write(models).await?;
println!("Deleted documents: {}", result.deleted_count);
Deleted documents: 4

O método bulk_write() retorna uma instância de estrutura SummaryBulkWriteResult da qual você pode acessar informações sobre sua operação em massa.

O tipo SummaryBulkWriteResult tem os seguintes campos:

  • inserted_count: o número de documentos inseridos

  • matched_count: o número de documentos correspondentes

  • modified_count: o número de documentos atualizados

  • upserted_count: o número de documentos atualizados

  • deleted_count: o número de documentos excluídos

Você também pode utilizar o método verbose_results() para visualizar informações detalhadas sobre cada operação. O método verbose_results() retorna uma instância de estrutura VerboseBulkWriteResult , que tem os seguintes campos:

  • delete_results: os resultados de cada operação de exclusão bem-sucedida

  • insert_results: os resultados de cada operação de inserção bem-sucedida

  • update_results: os resultados de cada operação de atualização bem-sucedida

  • summary: um resumo dos resultados de cada tipo de operação

O exemplo a seguir encadeia o método verbose_results() ao método bulk_write() e imprime os resultados das operações de atualização e exclusão:

let models = vec![
WriteModel::DeleteOne(
DeleteOneModel::builder()
.namespace(mushrooms.namespace())
.filter(doc! { "name": "oyster" })
.build(),
),
WriteModel::UpdateOne(
UpdateOneModel::builder()
.namespace(mushrooms.namespace())
.filter(doc! { "name": "chanterelle" })
.update(doc! { "$set": { "season": ["July", "August", "September"] } })
.build(),
),
];
let result = client.bulk_write(models).verbose_results().await?;
println!(
"Update results: {:?}\nDelete results: {:?}\n",
result.update_results, result.delete_results
);
Update results: {1: UpdateResult { matched_count: 1, modified_count: 1, upserted_id: None }}
Delete results: {0: DeleteResult { deleted_count: 1 }}

Você pode modificar o comportamento do método bulk_write() definindo os valores do campo BulkWriteOptions . Para definir esses campos de estrutura, encadeie os métodos correspondentes dos campos ao método bulk_write() .

A estrutura BulkWriteOptions contém os seguintes campos:

Campo
Descrição
Valor padrão
ordered
Whether the operations run in the order in which they were specified.
When set to true, one failed operation prevents subsequent operations from running.
When set to false, the server continues to attempt write operations if one fails.
Type: bool
true
bypass_document_validation
Whether document-level validation is bypassed.
Type: bool
false
comment
An arbitrary comment to help trace the operation through the database profiler, currentOp, and logs.
Type: Bson
None
let_vars
A map of parameter names and values to apply to all operations within the bulk write. Values must be constant or closed expressions that do not reference document fields.
Type: Document
None
write_concern
The write concern to use for this bulk operation.
Type: WriteConcern
Herda a preocupação de gravação do namespace

Este exemplo tenta executar operações de atualização e inserir na coleção mushrooms . O código a seguir define o campo ordered como false encadeando o método ordered() ao método bulk_write() :

let mushrooms: Collection<Document> = client.database("db").collection("mushrooms");
let models = vec![
WriteModel::UpdateOne(UpdateOneModel::builder()
.namespace(mushrooms.namespace())
.filter(doc! { "name": "portobello" })
.update(doc! { "$set": { "_id": 123 } })
.upsert(true)
.build()),
WriteModel::InsertOne(InsertOneModel::builder()
.namespace(mushrooms.namespace())
.document(doc! {
"name": "reishi",
"color": "red/brown",
"edible": true
})
.build()),
];
let result = client.bulk_write(models).ordered(false).await?;
println!(
"Inserted documents: {}\nDeleted documents: {}",
result.inserted_count, result.deleted_count
);
Error: Error { kind: BulkWrite(BulkWriteError { write_concern_errors: [], write_errors:
{0: WriteError { code: 66, code_name: None, message: "Plan executor error during update ::
caused by :: Performing an update on the path '_id' would modify the immutable field '_id'",
details: None }}, partial_result: Some(Summary(SummaryBulkWriteResult { inserted_count: 1,
matched_count: 0, modified_count: 0, upserted_count: 0, deleted_count: 0 })) }),
labels: ... }

O campo _id é imutável e não pode ser alterado em uma operação de atualização. Como o UpdateOneModel inclui instruções para atualizar este campo, a operação em massa retorna um BulkWriteError e executa somente a operação de inserção. Se você definir o campo ordered como true, o driver não tentará nenhuma operação subsequente após a operação de atualização malsucedida e o driver não inserirá nenhum documento.

Os exemplos anteriores nesta página executam operações em massa no namespace do db.mushrooms . No entanto, você pode realizar gravações em massa em vários namespaces em uma única chamada de método.

O exemplo a seguir insere um documento no namespace ingredients.sweet e um documento no namespace meals.dessert :

let sweet: Collection<Document> = client
.database("ingredients")
.collection("sweet");
let dessert: Collection<Document> = client
.database("meals")
.collection("dessert");
let models = vec![
InsertOneModel::builder()
.namespace(sweet.namespace())
.document(doc! { "name": "brown sugar", "price": 3.99 })
.build(),
InsertOneModel::builder()
.namespace(dessert.namespace())
.document(doc! { "name": "banana bread", "cook_time": 75 })
.build(),
];
let result = client.bulk_write(models).await?;
println!("Inserted documents: {}", result.inserted_count);
Inserted documents: 2

Para saber mais sobre operações em massa, consulte Operações de Gravação em Massa no manual do Servidor.

Voltar

Excluir