Docs Menu
Docs Home
/ / /
Kotlin Sync Driver
/

Access Data From a Cursor

On this page

  • Overview
  • Access Cursor Contents Iteratively
  • Retrieve Documents Individually
  • Retrieve All Documents
  • Tailable Cursors
  • Troubleshooting
  • API Documentation

In this guide, you can learn how to access data from a cursor with the Kotlin Sync driver.

A cursor is a mechanism that returns the results of a read operation in iterable batches. Because a cursor holds only a subset of documents at any given time, cursors reduce both memory consumption and the number of requests the driver sends to the server.

Whenever the Kotlin Sync driver performs a read operation that returns multiple documents, it automatically returns those documents in a cursor.

The examples in this guide use the restaurants collection in the sample_restaurants database from the Atlas sample datasets. To learn how to create a free MongoDB Atlas cluster and load the sample datasets, see the Get Started with Atlas guide.

The following Kotlin data class models the documents in this collection:

data class Restaurant(
@BsonId
val id: ObjectId,
val name: String
)

To iterate over the contents of a cursor, use the forEach() method, as shown in the following example:

val results = collection.find()
results.forEach { result ->
println(result)
}

Alternatively, use the use() method to implement a loop on the cursor:

val results = collection.find()
results.cursor().use { cursor ->
while (cursor.hasNext()) {
println(resultCursor.next())
}
}

Note

By default, MongoDB closes a cursor when the client has exhausted all the results in the cursor. The examples in this guide explicitly close cursors by using the close() method.

Retrieve documents from a cursor individually by calling the next() method.

The following example finds all documents in a collection with a name value of "Dunkin' Donuts". It then prints the first document in the cursor by calling the next() method.

val results = collection
.find<Restaurant>(eq(Restaurant::name.name, "Dunkin' Donuts"))
results.cursor().use { cursor ->
println(if (cursor.hasNext()) cursor.next()
else "No document matches the filter")
}
Restaurant(id=5eb3d668b31de5d588f42c66, name=Dunkin' Donuts)

Warning

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, access your cursor iteratively.

To retrieve all documents from a cursor, convert the cursor into a List as shown in the following example:

val results = collection.find<Restaurant>(eq(Restaurant::name.name, "Dunkin' Donuts"))
val resultsList = results.toList()
for (result in resultsList) {
println(result)
}
Restaurant(id=5eb3d668b31de5d588f42c66, name=Dunkin' Donuts)
Restaurant(id=5eb3d668b31de5d588f42ca0, name=Dunkin' Donuts)
Restaurant(id=5eb3d668b31de5d588f42b08, name=Dunkin' Donuts)
Restaurant(id=5eb3d668b31de5d588f42cd7, name=Dunkin' Donuts)
...

When querying on a capped collection, you can use a tailable cursor that remains open after the client exhausts the results in a cursor. To create a tailable cursor with capped collection, specify CursorType.TailableAwait to the cursorType method of a FindIterable object.

The following example creates a tailable cursor on a capped collection:

val results = collection.find<Document>().cursorType(CursorType.TailableAwait)

To learn more about tailable cursors and their usage, see the Tailable Cursors guide in the MongoDB Server manual.

Cursors in MongoDB can timeout on the server if they've been open for a long time without any operations being performed on them. This can lead to a CursorNotFound exception when you try to iterate through the cursor.

To learn more about any of the methods or types discussed in this guide, see the following API documentation:

Back

Retrieve Distinct Field Values