Visão geral
Neste guia, você pode aprender como usar o MongoDB Go Driver para executar operações em massa. As operações em massa reduzem o número de chamadas para o servidor , realizando várias operações de gravação em um único método.
As classes Collection e Client fornecem um método BulkWrite(). Você pode usar o método Collection.BulkWrite() para executar várias operações de gravação em uma única coleção. Você pode usar o método Client.BulkWrite() para executar gravações em massa em vários namespaces. No MongoDB, um namespace consiste em um nome de banco de dados e um nome de collection.
Importante
Requisitos de servidor para gravação em massa do cliente
Para executar operações em massa em uma instância do Client, certifique-se de que seu aplicação se conecte ao MongoDB Server v8.0 ou posterior
Dados de amostra
Os exemplos deste guia usam as seguintes estruturas:
Bookstruct, que modela documentos na collectiondb.books. Cada documento contém uma descrição de um livro que inclui o título, o autor e o comprimento da página.Poemstruct, que modela documentos na collectiondb.poems. Cada documento contém uma descrição de um poema que inclui o título, o autor e o ano de publicação.
type Book struct { Title string Author string Length int32 } type Poem struct { Title string Author string Year int32 }
Para executar os exemplos neste guia, carregue os dados de amostra nas collections books e poems usando o seguinte trecho:
bookColl := client.Database("db").Collection("books") poemColl := client.Database("db").Collection("poems") books := []any{ Book{Title: "My Brilliant Friend", Author: "Elena Ferrante", Length: 331}, Book{Title: "Lucy", Author: "Jamaica Kincaid", Length: 103}, } poems := []any{ Poem{Title: "Song of Myself", Author: "Walt Whitman", Year: 1855}, Poem{Title: "The Raincoat", Author: "Ada Limon", Year: 2018}, } bookInsert, err := bookColl.InsertMany(context.TODO(), books) poemInsert, err := poemColl.InsertMany(context.TODO(), poems)
Dica
Bancos de Dados e Coleções Inexistentes
Se o banco de dados e a collection necessários não existirem quando você executar uma operação de escrita, o servidor implicitamente os criará.
Gravação em massa de collections
Para executar uma operação em massa em um único namespace, chame o método BulkWrite() em uma collection e passe uma array de documentos WriteModel como parâmetro.
Definir modelos de gravação em massa da coleção
Para definir as operações de gravação para sua operação em massa em um namespace, crie um WriteModel para cada inserção, substituição, atualização ou exclusão.
InsertOneModel
Para definir uma operação de inserção para uma escrita em massa, crie um InsertOneModel especificando o documento que você deseja inserir. Para inserir vários documentos, crie um InsertOneModel para cada documento que você deseja inserir.
Você pode especificar o comportamento do InsertOneModel utilizando o seguinte método:
Método | Descrição |
|---|---|
| The document to insert. |
O exemplo a seguir cria duas instâncias InsertOneModel para inserir dois documentos na coleção books:
models := []mongo.WriteModel{ mongo.NewInsertOneModel().SetDocument(Book{Title: "Beloved", Author: "Toni Morrison", Length: 324}), mongo.NewInsertOneModel().SetDocument(Book{Title: "Outline", Author: "Rachel Cusk", Length: 258}), }
ReplaceOneModel
Para definir uma operação de substituição para uma escrita em massa, crie um ReplaceOneModel especificando o documento que deseja substituir e um documento de substituição. Para substituir vários documentos, crie um ReplaceOneModel para cada documento que deseja substituir.
Você pode especificar o comportamento do ReplaceOneModel utilizando os seguintes métodos:
Método | Descrição |
|---|---|
| The type of language collation to use when sorting results. |
| The query filter specifying which document to replace. |
| The index to use to scan for documents. |
| The document to replace the matched document with. |
| The sort order for matching documents. The replace operation
replaces only the first document according to the sort criteria. |
| Whether to insert a new document if the query filter doesn't match any documents. |
O exemplo a seguir cria um ReplaceOneModel para substituir um documento na coleção books na qual o valor title é "Lucy":
models := []mongo.WriteModel{ mongo.NewReplaceOneModel().SetFilter(bson.D{{"title", "Lucy"}}). SetReplacement(Book{Title: "On Beauty", Author: "Zadie Smith", Length: 473}), }
UpdateOneModel e UpdateManyModel
Para definir uma operação de atualização para uma escrita em massa, crie um UpdateOneModel especificando o documento que você deseja atualizar e um documento de atualização. Para atualizar vários documentos, use um UpdateManyModel.
Você pode especificar o comportamento de cada um dos modelos de atualização usando os seguintes métodos:
Método | Descrição |
|---|---|
| The array elements the update applies to. |
| The type of language collation to use when sorting results. |
| The query filter specifying which document to update. |
| The index to use to scan for documents. |
| The criteria to use when ordering matching documents.
This method is only available for the UpdateOneModel
class. |
| The modifications to apply on the matched documents. |
| Whether to insert a new document if the query filter doesn't match any documents. |
O exemplo a seguir cria um UpdateOneModel para atualizar um documento na collection books, diminuindo o length de um documento por 15 se o author for "Elena Ferrante":
models := []mongo.WriteModel{ mongo.NewUpdateOneModel().SetFilter(bson.D{{"author", "Elena Ferrante"}}). SetUpdate(bson.D{{"$inc", bson.D{{"length", -15}}}}), }
DeleteOneModel e DeleteManyModel
Para definir uma operação de exclusão para uma gravação em massa, crie um DeleteOneModel especificando o documento que você deseja excluir. Para excluir vários documentos, use o DeleteManyModel.
Você pode especificar o comportamento de cada um dos modelos de exclusão usando os seguintes métodos:
Método | Descrição |
|---|---|
| The type of language collation to use when sorting results. |
| The query filter specifying which document to delete. |
| The index to use to scan for documents. |
O exemplo a seguir cria um DeleteManyModel para excluir documentos na collection books na qual o length é maior que 300:
models := []mongo.WriteModel{ mongo.NewDeleteManyModel().SetFilter(bson.D{{"length", bson.D{{"$gt", 300}}}}), }
Modificar comportamento em nível de collection
Para modificar o comportamento de sua operação de gravação em massa, passe uma instância BulkWriteOptions para o método BulkWrite().
O tipo BulkWriteOptions permite que você configure opções usando os seguintes métodos:
Método | Descrição |
|---|---|
| Specifies whether the operation can opt-out of document level validation. Default: false |
| Specifies a comment to attach to the operation. Default: nil |
| |
| Specifies whether the driver stops performing write operations after an error occurs. Default: true |
Valor de retorno em nível de collection
O método BulkWrite() retorna um tipo BulkWriteResult, que inclui informações sobre a operação em massa.
O tipo BulkWriteResult contém as seguintes propriedades:
Propriedade | Descrição |
|---|---|
| O número de documentos inseridos. |
| O número de documentos correspondidos pelo filtro de query nas operações de atualização e substituição. |
| O número de documentos modificados por atualização e substituição de operações. |
| O número de documentos excluídos. |
| O número de documentos atualizados por atualização e substituição de operações. |
| Um mapa de um índice de operação para o |
| Um valor booleano que indica se a operação de gravação foi reconhecida. |
Ordem de execução em nível de coleção
Para especificar se a gravação em massa executa as operações em ordem, você pode definir a opção Ordered como um valor booleano. Para definir esta opção, especifique o campo Ordered de uma instância do BulkWriteOptions.
Pedido
Por padrão, o método BulkWrite() executa operações em massa para que você as adicione e pare se ocorrer um erro.
Dica
Isto é equivalente a passar um valor de true para o método SetOrdered(), como mostrado no seguinte código:
opts := options.BulkWrite().SetOrdered(true)
Não ordenado
Para executar operações de gravação em massa em qualquer ordem e continuar se ocorrer um erro, passe um valor de false para o método SetOrdered(). O método relata erros após a conclusão da operação.
O exemplo a seguir executa as seguintes ações em qualquer ordem:
Insere dois documentos
Substitui um documento onde o
titleé "Meu amigo brilhante" por um novo documentoAumenta o
lengthde cada documento em10se o valor atual delengthfor menor que200Exclui todos os documentos onde o valor de campo
authorinclui"Jam"
models := []mongo.WriteModel{ mongo.NewInsertOneModel().SetDocument(Book{Title: "Middlemarch", Author: "George Eliot", Length: 904}), mongo.NewInsertOneModel().SetDocument(Book{Title: "Pale Fire", Author: "Vladimir Nabokov", Length: 246}), mongo.NewReplaceOneModel().SetFilter(bson.D{{"title", "My Brilliant Friend"}}). SetReplacement(Book{Title: "Atonement", Author: "Ian McEwan", Length: 351}), mongo.NewUpdateManyModel().SetFilter(bson.D{{"length", bson.D{{"$lt", 200}}}}). SetUpdate(bson.D{{"$inc", bson.D{{"length", 10}}}}), mongo.NewDeleteManyModel().SetFilter(bson.D{{"author", bson.D{{"$regex", "Jam"}}}}), } // Specifies that the bulk write is unordered opts := options.BulkWrite().SetOrdered(false) // Runs the bulk write operation and prints a summary of the // data changes results, err := bookColl.BulkWrite(context.TODO(), models, opts) if err != nil { panic(err) } fmt.Printf("Number of documents inserted: %d\n", results.InsertedCount) fmt.Printf("Number of documents replaced or updated: %d\n", results.ModifiedCount) fmt.Printf("Number of documents deleted: %d\n", results.DeletedCount)
Number of documents inserted: 2 Number of documents replaced or updated: 2 Number of documents deleted: 1
Os seguintes documentos estão presentes na collection books após a operação em massa:
{"title":"Atonement","author":"Ian McEwan","length":351} {"title":"Middlemarch","author":"George Eliot","length":904} {"title":"Pale Fire","author":"Vladimir Nabokov","length":246}
Exemplo de operação em massa: arquivo completo
Observação
Exemplo de configuração
Esse exemplo se conecta a uma instância do MongoDB usando um URI de conexão. Para saber mais sobre como se conectar à sua instância do MongoDB, consulte o guia Como criar um MongoClient. Este exemplo também utiliza a coleção do restaurants no banco de dados do sample_restaurants incluído nos conjuntos de dados de amostra do Atlas. Você pode carregá-los em seu banco de dados na camada grátis do MongoDB Atlas seguindo o Guia de Introdução ao Atlas.
O exemplo a seguir é um arquivo totalmente executável que executa as seguintes ações:
Corresponde a um documento no qual o valor de campo
nameé"Towne Cafe"e o substitui por um novo documento com o valor de camponamedefinido como"New Towne Cafe"e o valor de campocuisinedefinido como"French"Corresponde a um documento no qual o valor do campo
nameéRiviera Caterere atualiza o valor do camponamepara"Riviera Cafe"
// Runs bulk write operations on a collection by using the Go driver package main import ( "context" "fmt" "log" "os" "github.com/joho/godotenv" "go.mongodb.org/mongo-driver/v2/bson" "go.mongodb.org/mongo-driver/v2/mongo" "go.mongodb.org/mongo-driver/v2/mongo/options" ) // Defines a Restaurant struct as a model for documents in the "restaurants" collection type Restaurant struct { Name string RestaurantId string `bson:"restaurant_id,omitempty"` Cuisine string `bson:"cuisine,omitempty"` Address any `bson:"address,omitempty"` Borough string `bson:"borough,omitempty"` Grades []any `bson:"grades,omitempty"` } func main() { if err := godotenv.Load(); err != nil { log.Println("No .env file found") } var uri string if uri = os.Getenv("MONGODB_URI"); uri == "" { log.Fatal("You must set your 'MONGODB_URI' environment variable. See\n\t https://www.mongodb.com/pt-br/docs/drivers/go/current/connect/mongoclient/#environment-variable") } client, err := mongo.Connect(options.Client().ApplyURI(uri)) if err != nil { panic(err) } defer func() { if err = client.Disconnect(context.TODO()); err != nil { panic(err) } }() coll := client.Database("sample_restaurants").Collection("restaurants") // Creates write models that specify replace and update operations models := []mongo.WriteModel{ mongo.NewReplaceOneModel().SetFilter(bson.D{{"name", "Towne Cafe"}}). SetReplacement(Restaurant{Name: "New Towne Cafe", Cuisine: "French"}), mongo.NewUpdateOneModel().SetFilter(bson.D{{"name", "Riviera Caterer"}}). SetUpdate(bson.D{{"$set", bson.D{{"name", "Riviera Cafe"}}}}), } // Specifies that the bulk write is ordered opts := options.BulkWrite().SetOrdered(true) // Runs a bulk write operation for the specified write operations results, err := coll.BulkWrite(context.TODO(), models, opts) if err != nil { panic(err) } // When you run this file for the first time, it should print output similar to the following: // Number of documents replaced or modified: 2 fmt.Printf("Number of documents replaced or modified: %d", results.ModifiedCount) }
Number of documents matched: 2 Number of documents modified: 2
Gravação em massa do cliente
Para executar uma operação em massa em vários namespaces, chame o método BulkWrite() no seu cliente e passe uma array de documentos ClientWriteModel como parâmetro.
Definir modelos de gravação em massa do cliente
Para especificar as operações de gravação para sua operação em massa em vários namespaces, crie um ClientWriteModel para cada inserção, substituição, atualização ou exclusão. Passe cada modelo de gravação para a estrutura ClientBulkWrite e especifique o banco de dados e a coleção de destino, conforme mostrado no código a seguir:
writes := []mongo.ClientBulkWrite{ {"<database name>", "<collection name>", <write model>}, ... }
ClientInsertOneModel
Para definir uma operação de inserção para uma escrita em massa, crie um ClientInsertOneModel especificando o documento que você deseja inserir. Para inserir vários documentos, crie um ClientInsertOneModel para cada documento que você deseja inserir.
Você pode especificar o comportamento do ClientInsertOneModel utilizando o seguinte método:
Método | Descrição |
|---|---|
| The document to insert. |
O exemplo a seguir cria duas instâncias ClientInsertOneModel para inserir um documento na coleção books e um documento na coleção poems:
bookInsertDoc := Book{Title: "Parable of the Sower", Author: "Octavia E. Butler", Length: 320} poemInsertDoc := Poem{Title: "Fame is a fickle food", Author: "Emily Dickinson", Year: 1659} writes := []mongo.ClientBulkWrite{ {"db", "books", mongo.NewClientInsertOneModel().SetDocument(bookInsertDoc)}, {"db", "poems", mongo.NewClientInsertOneModel().SetDocument(poemInsertDoc)}, }
ClientReplaceOneModel
Para definir uma operação de substituição para uma gravação em massa, crie um ClientReplaceOneModel especificando o documento que deseja substituir e um documento de substituição. Para substituir vários documentos, crie um ClientReplaceOneModel para cada documento que deseja substituir.
Você pode especificar o comportamento do ClientReplaceOneModel utilizando os seguintes métodos:
Método | Descrição |
|---|---|
| The type of language collation to use when sorting results. |
| The query filter specifying which document to replace. |
| The index to use to scan for documents. |
| The document to replace the matched document with. |
| The sort order for matching documents. The replace operation
replaces only the first document according to the sort criteria. |
| Whether to insert a new document if the query filter doesn't match any documents. |
Este exemplo cria instâncias do ClientReplaceOneModel para definir as seguintes operações:
Substituir operação na coleção
bookspara substituir um documento no qual o valortitleé"Lucy"Substituir operação na coleção
poemspara substituir um documento no qual o valortitleé"Song of Myself"
writes := []mongo.ClientBulkWrite{ {"db", "books", mongo.NewClientReplaceOneModel(). SetFilter(bson.D{{"title", "Lucy"}}). SetReplacement(Book{Title: "On Beauty", Author: "Zadie Smith", Length: 473})}, {"db", "poems", mongo.NewClientReplaceOneModel(). SetFilter(bson.D{{"title", "Song of Myself"}}). SetReplacement(Poem{Title: "America", Author: "Walt Whitman", Year: 1888})}, }
ClientUpdateOneModel e ClientUpdateManyModel
Para definir uma operação de atualização para uma escrita em massa, crie um ClientUpdateOneModel especificando o documento que você deseja atualizar e um documento de atualização. Para atualizar vários documentos, use um ClientUpdateManyModel.
Você pode especificar o comportamento de cada um dos modelos de atualização usando os seguintes métodos:
Método | Descrição |
|---|---|
| The array elements the update applies to. |
| The type of language collation to use when sorting results. |
| The query filter specifying which document to update. |
| The index to use to scan for documents. |
| The criteria to use when ordering matching documents.
This method is only available for the ClientUpdateOneModel class. |
| The modifications to apply on the matched documents. |
| Whether to insert a new document if the query filter
doesn't match any documents. |
Este exemplo cria instâncias do ClientUpdateOneModel para definir as seguintes operações:
Operação de atualização na coleção
bookspara atualizar um documento no qual o valorauthoré"Elena Ferrante"Operação de atualização na coleção
poemspara atualizar um documento no qual o valorauthoré"Ada Limon"
writes := []mongo.ClientBulkWrite{ {"db", "books", mongo.NewClientUpdateOneModel(). SetFilter(bson.D{{"author", "Elena Ferrante"}}). SetUpdate(bson.D{{"$inc", bson.D{{"length", -15}}}})}, {"db", "poems", mongo.NewClientUpdateOneModel(). SetFilter(bson.D{{"author", "Ada Limon"}}). SetUpdate(bson.D{{"author", "Ada Limón"}})}, }
Observação
Para atualizar todos os documentos que correspondem aos filtros de consulta do campo author no exemplo anterior, use instâncias ClientUpdateManyModel.
ClientDeleteOneModel e ClientDeleteManyModel
Para definir uma operação de exclusão para uma gravação em massa, crie um ClientDeleteOneModel especificando o documento que você deseja excluir. Para excluir vários documentos, use o ClientDeleteManyModel.
Você pode especificar o comportamento de cada um dos modelos de exclusão usando os seguintes métodos:
Método | Descrição |
|---|---|
| The type of language collation to use when sorting results. |
| The query filter specifying which document to delete. |
| The index to use to scan for documents. |
Este exemplo cria instâncias do ClientDeleteOneModel para definir as seguintes operações:
Operação Excluir na coleção
bookspara excluir um documento no qual o valorlengthé103Operação Excluir na coleção
poemspara excluir um documento no qual o valoryearé1855
writes := []mongo.ClientBulkWrite{ {"db", "books", mongo.NewClientDeleteOneModel(). SetFilter(bson.D{{"length", 103}})}, {"db", "poems", mongo.NewClientDeleteOneModel(). SetFilter(bson.D{{"year", 1855}})}, }
Modificar comportamento no nível do cliente
Para modificar o comportamento de sua operação de gravação em massa, passe uma instância ClientBulkWriteOptions para o método BulkWrite().
O tipo ClientBulkWriteOptions permite que você configure opções usando os seguintes métodos:
Método | Descrição |
|---|---|
| Specifies whether the operation can opt-out of document level validation. Default: false |
| Specifies whether the driver stops performing write operations after an error occurs. Default: true |
| Specifies a comment to attach to the operation. Default: nil |
| |
| Specifies the write concern for the operations. Default: nil |
| Specifies whether detailed information about each successful operation is
included in the result. Default: false |
Valor de retorno no nível do cliente
O método BulkWrite() retorna um tipo ClientBulkWriteResult, que inclui informações sobre a operação em massa.
O tipo ClientBulkWriteResult contém as seguintes propriedades:
Propriedade | Descrição |
|---|---|
| O número de documentos inseridos. |
| O número de documentos correspondidos pelo filtro de query nas operações de atualização e substituição. |
| O número de documentos modificados por atualização e substituição de operações. |
| O número de documentos excluídos. |
| O número de documentos atualizados por atualização e substituição de operações. |
| Um mapa de um índice de operação para o valor |
| Um mapa de um índice de operação para o valor |
| Um mapa de um índice de operação para o valor |
| Um valor booleano que indica se a operação de gravação foi reconhecida. |
| Um valor booleano que indica se o resultado contém resultados detalhados. |
Ordem de execução no nível do cliente
Para especificar se a gravação em massa executa as operações em ordem, você pode definir a opção Ordered como um valor booleano. Para definir esta opção, especifique o campo Ordered de uma instância do ClientBulkWriteOptions.
Pedido
Por padrão, o método BulkWrite() executa operações em massa para que você as adicione e pare se ocorrer um erro.
Dica
Isto é equivalente a passar um valor de true para o método SetOrdered(), como mostrado no seguinte código:
opts := options.ClientBulkWrite().SetOrdered(true)
Não ordenado
Para executar operações de gravação em massa em qualquer ordem e continuar se ocorrer um erro, passe um valor de false para o método SetOrdered(). O método relata erros após a conclusão da operação.
O exemplo a seguir executa as seguintes ações em qualquer ordem:
Insere um novo documento nas coleções
booksepoemsAtualiza um documento na coleção
poemsque tem um valortitlede"The Raincoat"Substitui um documento na coleção
booksque tem um valortitlede"My Brilliant Friend"
writes := []mongo.ClientBulkWrite{ {"db", "books", mongo.NewClientInsertOneModel(). SetDocument(Book{Title: "Middlemarch", Author: "George Eliot", Length: 904})}, {"db", "poems", mongo.NewClientInsertOneModel(). SetDocument(Poem{Title: "Mad Girl's Love Song", Author: "Sylvia Plath", Year: 1953})}, {"db", "poems", mongo.NewClientUpdateOneModel(). SetFilter(bson.D{{"title", "The Raincoat"}}). SetUpdate(bson.D{{"title", "The Conditional"}})}, {"db", "books", mongo.NewClientReplaceOneModel(). SetFilter(bson.D{{"title", "My Brilliant Friend"}}). SetReplacement(Book{Title: "The Story of a New Name", Author: "Elena Ferrante", Length: 480})}, } opts := options.ClientBulkWrite().SetOrdered(false) results, err := client.BulkWrite(context.TODO(), writes, opts) if err != nil { panic(err) } fmt.Printf("Number of documents inserted: %d\n", results.InsertedCount) fmt.Printf("Number of documents replaced or updated: %d\n", results.ModifiedCount)
Number of documents inserted: 2 Number of documents replaced or updated: 2
Informações adicionais
Para saber mais sobre como executar as operações mencionadas, consulte os seguintes guias:
Documentação da API
Para saber mais sobre os métodos ou tipos usados para gravações em massa de coleções, consulte a seguinte documentação da API:
Para saber mais sobre os métodos ou tipos usados para gravações em massa de cliente , consulte a seguinte documentação da API: