Overview
En esta guía, puedes aprender cómo acceder a los datos con un cursor.
Un cursor es un mecanismo que permite a una aplicación iterar sobre los resultados de una base de datos mientras mantiene solo una parte de ellos en la memoria en un momento determinado. Las operaciones de lectura que coinciden con varios documentos usan un cursor para devolver esos documentos en lotes, en lugar de todos a la vez.
Cursor de muestra
Una operación de lectura, como el método Find(), devuelve un Cursor que hace referencia a los documentos que coinciden con la operación. Para obtener un cursor, primero conéctese a su implementación y acceda a una colección, como se muestra en el siguiente ejemplo:
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/es/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")
Los ejemplos de esta guía utilizan la siguiente estructura MyStruct para modelar los documentos de la colección:
type MyStruct struct { MyProperty string }
El siguiente código inserta documentos de muestra en la colección:
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 obtener un cursor, llame al método Find() de la colección para ejecutar una query y devolver un cursor. El siguiente ejemplo pasa un filtro vacío para que coincida con todos los documentos de la colección y asigna el cursor resultante a una variable cursor:
cursor, err := coll.Find(context.TODO(), bson.D{}) if err != nil { panic(err) }
Cada sección de esta guía utiliza esta variable cursor. El driver desmarshala los documentos a los que hace referencia el cursor a la estructura MyStruct.
Importante
Un cursor no es seguro para gorutinas. No utilices el mismo cursor en varias gorutinas al mismo tiempo.
Recuperar documentos individualmente
Para recuperar documentos de tu cursor de manera individual mientras bloqueas la goroutine actual, utiliza el método Next().
El método retorna un documento si se cumplen todas las siguientes condiciones:
Un documento está disponible ahora o lo estará más adelante.
El controlador no produjo errores.
El contexto no ha expirado.
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 con seguimiento
Para intentar recuperar un documento sin bloquear la goroutine actual, utilice el método TryNext(). Utilice este enfoque cuando itere sobre un cursor con seguimiento.
El método retorna un documento si se cumplen todas las siguientes condiciones:
Actualmente, hay un documento disponible.
El controlador no produjo errores.
El contexto no ha expirado.
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 los documentos
Para rellenar una porción con todos los resultados de su query, utilice el 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
Memoria
Si la cantidad y el tamaño de los documentos devoluidos por tu query superan la memoria disponible de la aplicación, tu programa se bloqueará. Si esperas un conjunto de resultados grande, debes consumir tu cursor de forma iterativa.
Cierra el cursor
Cuando su aplicación ya no requiera un cursor, cierre el cursor con el método Close(). Este método libera los recursos que consume tu cursor tanto en la aplicación cliente como en el servidor de MongoDB.
defer cursor.Close(context.TODO())
Nota
Cuando recupera documentos individualmente mediante el método Next() o TryNext(), cierre siempre el cursor para liberar los recursos que consume.
Información Adicional
Para obtener más información sobre las operaciones mencionadas en esta guía, consulta las siguientes guías:
Documentación de la API
Para aprender más sobre cursores y cómo acceder a sus elementos, consulta la siguiente Documentación de la API: