Visão geral
Neste guia, você aprenderá a realizar operações compostas.
As operações compostas combinam uma operação de leitura e gravação em uma única operação. Se você executar uma operação de leitura e gravação separadamente, há uma chance de que outra pessoa altere o documento entre as duas operações. O MongoDB evita isso colocando um bloqueio de gravação no documento que você está modificando durante a operação composta.
O MongoDB é compatível com as seguintes operações compostas:
Dica
Para saber como executar operações compostas em mais de um documento ao mesmo tempo, consulte o guia Transações .
Dados de amostra
Os exemplos nesta aba usam o seguinte struct Course como um modelo para documentos na coleção courses:
type Course struct { Title string Enrollment int32 }
Para executar os exemplos nesta aba, carregue os dados de amostra na coleção db.courses com o seguinte trecho:
coll := client.Database("db").Collection("courses") docs := []interface{}{ Course{Title: "Representation Theory", Enrollment: 40}, Course{Title: "Early Modern Philosophy", Enrollment: 25}, Course{Title: "Animal Communication", Enrollment: 18}, } result, err := coll.InsertMany(context.TODO(), docs)
Cada documento contém uma descrição de um curso universitário que inclui o nome do curso e o número máximo de matrículas, correspondentes aos campos title e enrollment em cada documento.
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á.
Localize e exclua
O método FindOneAndDelete() encontra o primeiro documento que corresponde ao filtro de query especificado e o exclui. O método retorna um SingleResult contendo o documento excluído.
Observação
O método FindOneAndDelete() é uma operação atômica, o que significa que impede que qualquer outra operação de gravação altere o documento correspondente até que ele seja concluído. O método DeleteOne() também é uma operação atômica, mas difere do FindOneAndDelete() porque você não pode especificar uma ordem de classificação para os documentos correspondentes.
Para localizar um documento e excluí-lo em operações separadas, chame o método FindOne() seguido pelo método DeleteOne().
Modificar comportamento
Você pode modificar o comportamento do método FindOneAndDelete() passando um FindOneAndDeleteOptions. Se você não especificar um FindOneAndDeleteOptions, o driver utilizará os valores padrão para cada opção.
O tipo FindOneAndDeleteOptions permite a você configurar opções com os seguintes métodos:
Método | Descrição |
|---|---|
| The type of language collation to use when sorting results. Default: nil |
| The fields to include in the document returned. Default: nil |
| The sort fields and directions to order the documents matched. Default: nil |
| The index to use to scan for documents. Default: nil |
Exemplo
O exemplo a seguir utiliza o método FindOneAndDelete() para corresponder e excluir o primeiro documento em que o valor do campo enrollment seja menor que 20:
filter := bson.D{{"enrollment", bson.D{{"$lt", 20}}}} var deletedDoc Course err := coll.FindOneAndDelete(context.TODO(), filter).Decode(&deletedDoc) if err != nil { panic(err) } res, _ := bson.MarshalExtJSON(deletedDoc, false, false) fmt.Println(string(res))
{"title":"Animal Communication","enrollment":18}
Encontrar e atualizar
O método FindOneAndUpdate() localiza o primeiro documento que corresponde ao filtro de query especificado e o atualiza de acordo com o documento de atualização. O método retorna um SingleResult que contém o documento correspondente.
Observação
O método FindOneAndUpdate() é uma operação atômica, o que significa que impede que qualquer outra operação de gravação altere o documento correspondente até que ele seja concluído. O método UpdateOne() também é uma operação atômica, mas difere do FindOneAndUpdate() porque você não pode especificar uma ordem de classificação para os documentos correspondentes.
Para localizar um documento e atualizá-lo em operações separadas, chame o método FindOne() e, em seguida, chame o método UpdateOne().
Modificar comportamento
Você pode modificar o comportamento do método FindOneAndUpdate() passando um FindOneAndUpdateOptions. Se você não especificar um FindOneAndUpdateOptions, o driver utilizará os valores padrão para cada opção.
O tipo FindOneAndUpdateOptions permite a você configurar opções com os seguintes métodos:
Método | Descrição |
|---|---|
| The array elements the update applies to. Default: nil |
| Whether to allow the write operation to opt-out of document level validation. Default: false |
| The type of language collation to use when sorting results. Default: nil |
| The fields to include in the document returned. Default: nil |
| Whether to return the original or updated document in the SingleResult.Default: options.Before |
| The sort fields and directions to order the documents matched. Default: nil |
| Whether to insert a new document if the query filter doesn't match any documents. Default: false |
| The index to use to scan for documents. Default: nil |
Exemplo
O exemplo a seguir usa o método FindOneAndUpdate() para executar as ações a seguir em ordem:
Corresponde ao primeiro documento onde o valor do campo
titleinclui "Moderno"Atualiza o valor de campo
enrollmentdo documento correspondente para32Retorna o documento atualizado
filter := bson.D{{"title", bson.D{{"$regex", "Modern"}}}} update := bson.D{{"$set", bson.D{{"enrollment", 32}}}} opts := options.FindOneAndUpdate().SetReturnDocument(options.After) var updatedDoc Course err := coll.FindOneAndUpdate(context.TODO(), filter, update, opts).Decode(&updatedDoc) if err != nil { panic(err) } res, _ := bson.MarshalExtJSON(updatedDoc, false, false) fmt.Println(string(res))
{"title":"Early Modern Philosophy","enrollment":32}
Encontrar e substituir
O método FindOneAndReplace() localiza o primeiro documento que corresponde ao filtro de query especificado e o substitui pelo documento de substituição. O método retorna um SingleResult contendo o documento correspondente.
Observação
Este método é diferente do método ReplaceOne(). FindOneAndReplace() executa localizar e substituir como uma única operação e elimina a possibilidade de alguém alterar um documento entre ambas as operações. Ao usar FindOneAndReplace(), você também pode definir uma ordem de classificação nos documentos correspondentes.
Para localizar um documento e substituí-lo em operações separadas, chame o método FindOne() seguido pelo método ReplaceOne().
Modificar comportamento
Você pode modificar o comportamento do método FindOneAndReplace() passando um FindOneAndReplaceOptions. Se você não especificar um FindOneAndReplaceOptions, o driver utilizará os valores padrão para cada opção.
O tipo FindOneAndReplaceOptions permite a você configurar opções com os seguintes métodos:
Método | Descrição |
|---|---|
| Whether to allow the write operation to opt-out of document level validation. Default: false |
| The type of language collation to use when sorting results. Default: nil |
| The fields to include in the document returned. Default: nil |
| Whether to return the original or replaced document in the SingleResult.Default: nil |
| The sort fields and directions to order the documents matched. Default: nil |
| Whether to insert a new document if the query filter doesn't match any documents. Default: false |
| The index to use to scan for documents. Default: nil |
Exemplo
O exemplo a seguir usa o método FindOneAndReplace() para executar as ações a seguir em ordem:
Corresponde ao primeiro documento onde o
titleé "teoria de representação"Substitui o documento correspondente por um novo documento onde o
titleé "Teoria Combinatória" e oenrollmenté35
filter := bson.D{{"title", "Representation Theory"}} replacement := Course{Title: "Combinatorial Theory", Enrollment: 35} var outdatedDoc Course err := coll.FindOneAndReplace(context.TODO(), filter, replacement).Decode(&previousDoc) if err != nil { panic(err) } res, _ := bson.MarshalExtJSON(outdatedDoc, false, false) fmt.Println(string(res))
{"title":"Representation Theory","enrollment":40}
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 qualquer um dos métodos ou tipos discutidos neste guia, consulte a seguinte documentação da API: