Access Data From a Cursor
On this page
Overview
In this guide, you can learn how to access data with a cursor.
A cursor is a mechanism that allows an application to iterate over database results while holding only a subset of them in memory at a given time. Read operations that match multiple documents use a cursor to return those documents in batches as opposed to all at once.
Sample Cursor
Each section uses the following cursor
variable, which is a
Cursor
struct that contains all the documents in a collection:
cursor, err := coll.Find(context.TODO(), bson.D{}) if err != nil { panic(err) }
In the examples in this guide, the driver unmarshals documents held in
the cursor
variable to a sample MyStruct
struct.
Important
A cursor is not goroutine safe. Do not use the same cursor in multiple goroutines at the same time.
Retrieve Documents Individually
To retrieve documents from your cursor individually while blocking the
current goroutine, use the Next()
method.
The method returns a document if all of the following conditions are met:
A document is currently or will later be available.
The driver didn't throw any errors.
The context didn't expire.
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) }
Tailable Cursor
To attempt retrieving a document from a tailable cursor, use the TryNext()
method.
The method returns a document if all of the following conditions are met:
A document is currently available.
The driver didn't throw any errors.
The context didn't expire.
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 } }
Retrieve All Documents
To populate an array with all of your query results, use the All()
method:
var results []MyStruct if err = cursor.All(context.TODO(), &results); err != nil { panic(err) } for _, result := range results { fmt.Printf("%+v\n", result) }
Important
Memory
If the number and size of documents returned by your query exceeds available application memory, your program will crash. If you except a large result set, you should consume your cursor iteratively.
Close the Cursor
When your application no longer needs to use a cursor, close the cursor
with the Close()
method. This method frees the resources your cursor
consumes in both the client application and the MongoDB server.
defer cursor.Close(context.TODO())
Note
Close the cursor when you retrieve documents individually because those methods make a cursor tailable.
Additional Information
To learn more about the operations discussed in this guide, see the following guides:
API Documentation
To learn more about cursors and how to access their elements, see the following API Documentation: