Visão geral
Neste guia, você pode aprender como acessar dados com um cursor.
Um cursor é um mecanismo que permite que uma aplicação itere sobre os resultados do banco de dados enquanto mantém apenas um subconjunto deles na memória em um determinado momento. Operações de leitura que correspondem a vários documentos usam um cursor para retornar esses documentos em lotes em vez de todos de uma vez.
Amostra de cursor
Uma operação de leitura, como o método Find(), retorna um Cursor que faz referência aos documentos correspondidos pela operação. Para obter um cursor, primeiro conecte-se à sua implantação e acesse uma coleção, conforme mostrado no exemplo a seguir:
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/usage-examples/") } 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("db").Collection("sample_data")
Os exemplos neste guia utilizam o seguinte MyStruct estruturado como um modelo para documentos na coleção:
type MyStruct struct { MyProperty string }
O código a seguir insere documentos de amostra na coleção:
docs := []any{ MyStruct{MyProperty: "Beach House"}, MyStruct{MyProperty: "Office"}, MyStruct{MyProperty: "Bungalow"}, } result, err := coll.InsertMany(context.TODO(), docs) if err != nil { panic(err) }
Para obter um cursor, chame o método Find() na coleção para executar uma query e retornar um cursor. O exemplo a seguir passa um filtro vazio para corresponder a todos os documentos da coleção e atribui o cursor resultante a uma variável cursor:
cursor, err := coll.Find(context.TODO(), bson.D{}) if err != nil { panic(err) }
Cada seção neste guia usa esta variável cursor. O driver descompacta os documentos que o cursor referencia para a estrutura MyStruct.
Importante
Um cursor não é groutine seguro. Não use o mesmo cursor em várias goroutines ao mesmo tempo.
Recuperar documentos individualmente
Para recuperar documentos do cursor individualmente enquanto bloqueia a goroutine atual, use o método Next().
O método retorna um documento se todas as seguintes condições forem atendidas:
Um documento está atualmente ou estará disponível posteriormente.
O driver não lançou nenhum erro.
O contexto não expirou.
for cursor.Next(context.TODO()) { var result MyStruct if err := cursor.Decode(&result); err != nil { log.Fatal(err) } fmt.Printf("%+v\n", result) } if err := cursor.Err(); err != nil { log.Fatal(err) }
Cursor atualizado
Para tentar recuperar um documento sem bloquear a goroutine atual, use o TryNext() método. Use essa abordagem ao iterar sobre um cursor persistente.
O método retorna um documento se todas as seguintes condições forem atendidas:
Um documento está atualmente disponível.
O driver não lançou nenhum erro.
O contexto não expirou.
for { if cursor.TryNext(context.TODO()) { var result MyStruct if err := cursor.Decode(&result); err != nil { log.Fatal(err) } fmt.Printf("%+v\n", result) continue } if err := cursor.Err(); err != nil { log.Fatal(err) } if cursor.ID() == 0 { break } }
Recuperar todos os documentos
Para preencher uma fatia com todos os resultados da sua query, utilize o método All():
var results []MyStruct if err := cursor.All(context.TODO(), &results); err != nil { panic(err) } for _, result := range results { fmt.Printf("%+v\n", result) }
{MyProperty:Beach House} {MyProperty:Office} {MyProperty:Bungalow}
Importante
Memória
Se o número e o tamanho dos documentos retornados pela sua query excederem a memória disponível do aplicação , seu programa falhará. Se você espera um definir grande, deve consumir o cursor iterativamente.
Fechar o cursor
Quando seu aplicativo não exigir mais um cursor, feche o cursor com o método Close(). Esse método libera os recursos que o cursor consome no aplicativo cliente e no servidor MongoDB.
defer cursor.Close(context.TODO())
Observação
Ao recuperar documentos individualmente usando o Next() TryNext() método ou, sempre feche o cursor para liberar os recursos que ele consome.
Informações adicionais
Para saber mais sobre as operações abordadas neste guia, consulte os seguintes guias:
Documentação da API
Para saber mais sobre cursores e como acessar seus elementos, consulte a seguinte documentação da API: