Para agentes de IA: um índice de documentação está disponível em https://www.mongodb.com/pt-br/docs/llms.txt — as versões de markdown de todas as páginas estão disponíveis anexando .md a qualquer caminho de URL.
Menu Docs

Operações em massa

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

O namespace no qual a inserção é executada.
Tipo: Namespace

document

O documento a inserir.
Tipo: 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 personalizados 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

O namespace no qual a operação é executada.
Tipo: Namespace

filter

O filtro que corresponde ao documento que você deseja substituir.
Tipo: Document

replacement

O documento de substituição.
Tipo: Document

collation

(Opcional) O agrupamento a ser usado ao classificar os resultados. Para saber mais sobre agrupamentos, consulte o guia Agrupamentos.
Tipo: Document

hint

(Opcional) O índice a ser usado para a operação. Para aprender mais sobre índice, consulte o guia Índices .
Tipo: Bson

upsert

(Opcional) Se um novo documento será criado se nenhum documento corresponder ao filtro.
Por padrão, este campo é configurado para false.
Tipo: 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

O namespace no qual a operação é executada.
Tipo: Namespace

filter

O filtro que corresponde a um ou mais documentos que você deseja atualizar. Quando especificado em um UpdateOneModel, somente o primeiro documento correspondente será atualizado. Quando especificado em um UpdateManyModel, todos os documentos correspondentes serão atualizados.
Tipo: Document

update

A atualização a ser executada.
Tipo: UpdateModifications

array_filters

(Opcional) Um conjunto de filtros que especificam a quais elementos de array uma atualização se aplica se você estiver atualizando um campo com valor de array.
Tipo: Array

collation

(Opcional) O agrupamento a ser usado ao classificar os resultados. Para saber mais sobre agrupamentos, consulte o guia Agrupamentos.
Tipo: Document

hint

(Opcional) O índice a ser usado para a operação. Para aprender mais sobre índice, consulte o guia Índices .
Tipo: Bson

upsert

(Opcional) Se um novo documento será criado se nenhum documento corresponder ao filtro. Por padrão, este campo é configurado para false.
Tipo: 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

O namespace no qual a operação é executada.
Tipo: Namespace

filter

O filtro que corresponde a um ou mais documentos que você deseja excluir. Quando especificado em um DeleteOneModel, somente o primeiro documento correspondente será excluído. Quando especificado em um DeleteManyModel, todos os documentos correspondentes serão excluídos.
Tipo: Document

collation

(Opcional) O agrupamento a ser usado ao classificar os resultados. Para saber mais sobre agrupamentos, consulte o guia Agrupamentos.
Tipo: Document

hint

(Opcional) O índice a ser usado para a operação. Para aprender mais sobre índice, consulte o guia Índices .
Tipo: 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

Se as operações são executadas na ordem em que foram especificadas.
Quando definido como true, uma operação com falha impede que as operações subsequentes sejam executadas.
Quando definido como false, o servidor continua a tentar operações de gravação se uma falhar.
Tipo: bool

true

bypass_document_validation

Se a validação de nível de documento é ignorada.
Tipo: bool

false

comment

Um comentário arbitrário para ajudar a rastrear a operação através do profiler de banco de dados, currentOp e logs.
Tipo: Bson

None

let_vars

Um mapa de nomes e valores de parâmetros a serem aplicados a todas as operações dentro da gravação em massa. Os valores devem ser expressões constantes ou fechadas que não façam referência aos campos do documento.
Tipo: Document

None

write_concern

O write concern a ser usado para esta operação em massa.
Tipo: 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.

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