For AI agents: a documentation index is available at https://www.mongodb.com/docs/llms.txt — markdown versions of all pages are available by appending .md to any URL path.
Docs Menu

Access Data From a Cursor

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.

A read operation such as the Find() method returns a Cursor that references the documents matched by the operation. To obtain a cursor, first connect to your deployment and access a collection, as shown in the following example:

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/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")

The examples in this guide use the following MyStruct struct to model the documents in the collection:

type MyStruct struct {
MyProperty string
}

The following code inserts sample documents into the collection:

docs := []any{
MyStruct{MyProperty: "Beach House"},
MyStruct{MyProperty: "Office"},
MyStruct{MyProperty: "Bungalow"},
}
result, err := coll.InsertMany(context.TODO(), docs)
if err != nil {
panic(err)
}

To obtain a cursor, call the Find() method on the collection to run a query and return a cursor. The following example passes an empty filter to match all documents in the collection and assigns the resulting cursor to a cursor variable:

cursor, err := coll.Find(context.TODO(), bson.D{})
if err != nil {
panic(err)
}

Each section in this guide uses this cursor variable. The driver unmarshals the documents that the cursor references to the 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 to retrieve a document without blocking the current goroutine, use the TryNext() method. Use this approach when you iterate over a tailable cursor.

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 a slice 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)
}
{MyProperty:Beach House}
{MyProperty:Office}
{MyProperty:Bungalow}

Important

Memory

If the number and size of documents returned by your query exceeds available application memory, your program will crash. If you expect 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

When you retrieve documents individually by using the Next() or TryNext() method, always close the cursor to free the resources that it consumes.

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: