Docs Menu
Docs Home
/ / /
Go Driver
/ / /

Access Data From a Cursor

On this page

  • Overview
  • Sample Cursor
  • Retrieve Documents Individually
  • Tailable Cursor
  • Retrieve All Documents
  • Close the Cursor
  • Additional Information
  • API Documentation

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 rather than all at once.

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.

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)
}

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
}
}

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.

When your application no longer requires 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.

To learn more about the operations discussed in this guide, see the following guides:

To learn more about cursors and how to access their elements, see the following API Documentation:

← Retrieve Data