Visão geral
Neste guia, você pode aprender como recuperar dados de suas coleções MongoDB usando operações de leitura.
As operações de leitura permitem que fazer o seguinte:
Recupere documentos de suas collections usando operações de localização
Realize transformações em documentos em suas coleções usando operações de agregação
Dados de amostra
Os exemplos nesta aba usam o seguinte struct Tea
como um modelo para documentos na coleção tea
:
type Tea struct { Item string `bson:"item,omitempty"` Rating int32 `bson:"rating,omitempty"` DateOrdered time.Time `bson:"date_ordered,omitempty"` }
Para executar os exemplos neste guia, carregue estes documentos na coleção tea
no banco de dados do db
utilizando o seguinte trecho:
coll := client.Database("db").Collection("tea") docs := []interface{}{ Tea{Item: "Masala", Rating: 10, DateOrdered: time.Date(2009, 11, 17, 0, 0, 0, 0, time.Local)}, Tea{Item: "Sencha", Rating: 7, DateOrdered: time.Date(2009, 11, 18, 0, 0, 0, 0, time.Local)}, Tea{Item: "Masala", Rating: 9, DateOrdered: time.Date(2009, 11, 12, 0, 0, 0, 0, time.Local)}, Tea{Item: "Masala", Rating: 8, DateOrdered: time.Date(2009, 12, 1, 0, 0, 0, 0, time.Local)}, Tea{Item: "Sencha", Rating: 10, DateOrdered: time.Date(2009, 12, 17, 0, 0, 0, 0, time.Local)}, Tea{Item: "Hibiscus", Rating: 4, DateOrdered: time.Date(2009, 12, 18, 0, 0, 0, 0, time.Local)}, } result, err := coll.InsertMany(context.TODO(), docs)
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á.
Cada documento descreve a variedade de chá que um cliente pediu, sua classificação e a data do pedido. Estas descrições correspondem aos campos item
, rating
e date_ordered
.
Encontrar operações
Use localizar operações para recuperar dados do MongoDB. As operações de localização consistem nos métodos Find()
e FindOne()
.
Localizar vários documentos
O método Find()
espera que você passe um tipo Context
e um filtro de query. O método retorna todos os documentos que correspondem ao filtro como um tipo Cursor
.
O exemplo seguinte passa um contexto, filtro e FindOptions
para o método Find()
, que executa as seguintes ações:
Corresponde aos documentos onde o valor de
rating
está entre5
e9
(exclusivo)Classifica os documentos correspondentes em ordem crescente por
date_ordered
filter := bson.D{ {"$and", bson.A{ bson.D{{"rating", bson.D{{"$gt", 5}}}}, bson.D{{"rating", bson.D{{"$lt", 9}}}}, }}, } sort := bson.D{{"date_ordered", 1}} opts := options.Find().SetSort(sort) // Retrieves documents that match the filter and prints them as structs cursor, err := coll.Find(context.TODO(), filter, opts) if err != nil { panic(err) } var results []Tea if err = cursor.All(context.TODO(), &results); err != nil { panic(err) } for _, result := range results { res, _ := bson.MarshalExtJSON(result, false, false) fmt.Println(string(res)) }
{"item":"Sencha","rating":7,"date_ordered":"2009-11-18T05:00:00Z"} {"item":"Masala","rating":8,"date_ordered":"2009-12-01T05:00:00Z"}
Para saber como acessar dados usando um cursor, consulte o guia Acessar dados de um cursor.
encontrar documentos vários Exemplo: 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 encontra todos os documentos na collection restaurants
nos quais o valor de cuisine
é "Italian"
. O exemplo retorna um cursor que referencia os documentos correspondentes e descompacta os documentos em uma fatia:
// Retrieves documents that match a query filter by using the Go driver package main import ( "context" "encoding/json" "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" ) // Creates a Restaurant struct as a model for documents in the restaurants collection type Restaurant struct { ID bson.ObjectID `bson:"_id"` Name string RestaurantId string `bson:"restaurant_id"` Cuisine string Address interface{} Borough string Grades interface{} } 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 a query filter to match documents in which the "cuisine" // is "Italian" filter := bson.D{{"cuisine", "Italian"}} // Retrieves documents that match the query filter cursor, err := coll.Find(context.TODO(), filter) if err != nil { panic(err) } // Unpacks the cursor into a slice var results []Restaurant if err = cursor.All(context.TODO(), &results); err != nil { panic(err) } // Prints the results of the find operation as structs for _, result := range results { output, err := json.MarshalIndent(result, "", " ") if err != nil { panic(err) } fmt.Printf("%s\n", output) } }
// results truncated ... { ... , "Name" : "Epistrophy Cafe", "RestaurantId": "41117553", "Cuisine" : "Italian", ... }, { ... , "Name" : "Remi", "RestaurantId": "41118090", "Cuisine" : "Italian", ... }, { ... , "Name" : "Sant Ambroeus", "RestaurantId": "41120682", "Cuisine" : "Italian", ... }, ...
Encontrar um documento
O método FindOne()
espera que você passe um tipo de Context
e um filtro de query. O método retorna o primeiro documento que corresponde ao filtro como um tipo SingleResult
.
O exemplo seguinte passa um contexto, filtro e FindOneOptions
para o método FindOne()
, que executa as seguintes ações:
Corresponde a documentos onde o valor
date_ordered
é igual ou anterior a 30 de novembro de 2009Ignora os dois primeiros documentos correspondentes
filter := bson.D{{"date_ordered", bson.D{{"$lte", time.Date(2009, 11, 30, 0, 0, 0, 0, time.Local)}}}} opts := options.FindOne().SetSkip(2) // Retrieves a document that matches the filter and prints it as // a struct var result Tea err = coll.FindOne(context.TODO(), filter, opts).Decode(&result) if err != nil { if err == mongo.ErrNoDocuments { fmt.Println("No documents found") } else { panic(err) } } res, _ := bson.MarshalExtJSON(result, false, false) fmt.Println(string(res))
{"item":"Masala","rating":9,"date_ordered":"2009-11-12T05:00:00Z"}
Para ver um exemplo que usa FindOne()
e faz queries usando um valor de ObjectId
específico, consulte a seção Encontrar um por exemplo de ObjectId nesta página.
Para saber como acessar dados de um tipo SingleResult
, consulte Unmarshalling no guia BSON.
Encontre um por exemplo de ObjectId
Este exemplo define uma variável id
com um valor do tipo ObjectId
e utiliza id
para especificar um filtro de query. O filtro corresponde a um documento com um valor de campo _id
que corresponde à variável id
. Este exemplo query o seguinte documento com base em seu valor _id
:
{ _id: ObjectId('65170b42b99efdd0b07d42de'), item: "Hibiscus", rating : 4, date_ordered : 2009-12-18T05:00:00.000+00:00 }
O código abaixo passa o filtro e uma instância do FindOneOptions
como parâmetros para o método do FindOne()
para executar as seguintes ações:
Combine o documento com o valor de
ObjectId
especificadoProjete somente os campos
Item
eRating
do documento correspondente
id, err := bson.ObjectIDFromHex("65170b42b99efdd0b07d42de") if err != nil { panic(err) } // Creates a filter to match a document that has the specified // "_id" value filter := bson.D{{"_id", id}} opts := options.FindOne().SetProjection(bson.D{{"item", 1}, {"rating", 1}}) // Retrieves a document that matches the filter and prints it as // a struct var result Tea err = coll.FindOne(context.TODO(), filter, opts).Decode(&result) if err != nil { if err == mongo.ErrNoDocuments { fmt.Println("No documents found") } else { panic(err) } } res, _ := bson.MarshalExtJSON(result, false, false) fmt.Println(string(res))
{"item":"Hibiscus","rating":4}
Observação
O driver Go gera automaticamente um valor ObjectId
exclusivo para cada campo _id
do documento, portanto, seu valor ObjectId
pode ser diferente do exemplo de código anterior. Para obter mais informações sobre o campo _id
, consulte a seção _id Field da página Inserir um documento.
encontrar um documento Exemplo: 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 localiza e retorna o primeiro documento na collection restaurants
em que o valor de name
é "Bagels N Buns"
:
// Retrieves a document that matches a query filter by using the Go driver package main import ( "context" "encoding/json" "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" ) // Creates a Restaurant struct as a model for documents in the restaurants collection type Restaurant struct { ID bson.ObjectID `bson:"_id"` Name string RestaurantId string `bson:"restaurant_id"` Cuisine string Address interface{} Borough string Grades []interface{} } 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 a query filter to match documents in which the "name" is // "Bagels N Buns" filter := bson.D{{"name", "Bagels N Buns"}} // Retrieves the first matching document var result Restaurant err = coll.FindOne(context.TODO(), filter).Decode(&result) // Prints a message if no documents are matched or if any // other errors occur during the operation if err != nil { if err == mongo.ErrNoDocuments { return } panic(err) } output, err := json.MarshalIndent(result, "", " ") if err != nil { panic(err) } fmt.Printf("%s\n", output) }
// results truncated { "ID": "5eb3d668b31de5d588f42950", "Name": "Bagels N Buns", "RestaurantId": "40363427" "Address": [...], "Borough": "Staten Island", "Cuisine": "Delicatessen", "Grades": [...] }
Modificar comportamento
Você pode modificar o comportamento de Find()
e FindOne()
passando uma instância FindOptions
ou FindOneOptions
. Se você não especificar nenhuma opção, o driver usará os valores padrão para cada opção.
Você pode configurar as opções normalmente usadas em ambos os tipos com os seguintes métodos:
Método | Descrição |
---|---|
| The type of language collation to use when sorting results. Default: nil |
| The maximum number of documents to return. Default: 0 This option is not available for FindOneOptions . The
FindOne() method internally uses SetLimit(-1) . |
| The fields to include in the returned documents. Default: nil |
| The number of documents to skip. Default: 0 |
| The field and type of sort to order the matched documents. You can specify an ascending or descending sort. Default: none |
Operações de agregação
Use operações de aggregation para recuperar e transformar dados do MongoDB. Execute operações de aggregation usando o método Aggregate()
.
Agregação
O método Aggregate()
espera que você passe um tipo Context
e um pipeline de agregação. Um pipeline de agregação define como transformar dados por meio de estágios. Algumas das etapas são combinar documentos, renomear campos e agrupar valores.
O método retorna os documentos resultantes em um tipo Cursor
. Se você omitir o estágio $match, o pipeline continuará usando todos os documentos da coleção.
Para saber como acessar dados em um cursor, consulte Como acessar dados de um cursor.
Modificar comportamento
O método Aggregate()
opcionalmente usa um tipo AggregateOptions
, que representa opções que você pode usar para modificar seu comportamento. Se você não especificar nenhuma opção, o driver usará os valores padrão para cada opção.
O tipo AggregateOptions
permite a você configurar opções com os seguintes métodos:
Método | Descrição |
---|---|
| Whether to write to temporary files. Default: false |
| The number of documents to return in each batch. Default: none |
| Whether to allow the write to opt-out of document level validation. Default: false |
| The type of language collation to use when sorting results. Default: nil |
| The maximum amount of time for the server to wait on new documents to satisfy a tailable cursor query. Default: nil |
| An arbitrary string or document that allows you to trace the operation through the database profiler, currentOp, and logs. Default: "" |
| The index to use to scan for documents to retrieve. Default: nil |
| Specifies parameters for the aggregate expression, which improves command readability by separating the variables from the query text. Default: none |
Exemplo
O exemplo abaixo passa um contexto e uma aggregation pipeline que executa as seguintes ações:
Agrupa avaliações por item pedido
Calcula a classificação média para cada item
groupStage := bson.D{ {"$group", bson.D{ {"_id", "$item"}, {"average", bson.D{ {"$avg", "$rating"}, }}, }}} cursor, err := coll.Aggregate(context.TODO(), mongo.Pipeline{groupStage}) if err != nil { panic(err) } // Prints the average "rating" for each item var results []bson.M if err = cursor.All(context.TODO(), &results); err != nil { panic(err) } for _, result := range results { fmt.Printf("%v had an average rating of %v \n", result["_id"], result["average"]) }
Sencha had an average rating of 8.5 Hibiscus had an average rating of 4 Masala had an average rating of 9
Para saber mais sobre como construir um pipeline de agregação, consulte a página manual do servidor MongoDB em Agregação.
Informações adicionais
Para saber mais sobre 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: