Skip to content

Commit 9e3526c

Browse files
committed
DOCSP-41139: Cursors
1 parent c8d9955 commit 9e3526c

File tree

3 files changed

+235
-0
lines changed

3 files changed

+235
-0
lines changed

source/includes/read/cursors.kt

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package org.example
2+
import com.mongodb.ConnectionString
3+
import com.mongodb.CursorType
4+
import com.mongodb.MongoClientSettings
5+
import com.mongodb.client.model.Filters.eq
6+
import com.mongodb.kotlin.client.MongoClient
7+
import org.bson.codecs.pojo.annotations.BsonId
8+
import org.bson.types.ObjectId
9+
10+
// start-data-class
11+
data class Restaurant(
12+
@BsonId
13+
val id: ObjectId,
14+
val name: String
15+
)
16+
// end-data-class
17+
18+
fun main() {
19+
val uri = "<connection string URI>"
20+
21+
val settings = MongoClientSettings.builder()
22+
.applyConnectionString(ConnectionString(uri))
23+
.retryWrites(true)
24+
.build()
25+
26+
val mongoClient = MongoClient.create(settings)
27+
val database = mongoClient.getDatabase("sample_restaurants")
28+
val collection = database.getCollection<Restaurant>("restaurants")
29+
30+
// start-cursor-iterate
31+
val results = collection.find()
32+
33+
results.forEach { result ->
34+
println(results)
35+
}
36+
// end-cursor-iterate
37+
38+
// start-cursor-next
39+
val results = collection.find<Restaurant>(eq(Restaurant::name.name, "Dunkin' Donuts"))
40+
41+
println(results.cursor().next())
42+
// end-cursor-next
43+
44+
// start-cursor-list
45+
val results = collection.find<Restaurant>(eq(Restaurant::name.name, "Dunkin' Donuts"))
46+
val resultsList = results.toList()
47+
48+
for (result in resultsList) {
49+
println(result)
50+
}
51+
// end-cursor-list
52+
53+
// start-cursor-close
54+
val results = collection.find<Restaurant>()
55+
56+
// Handle your results here
57+
58+
results.cursor().close()
59+
// end-cursor-close
60+
61+
// start-tailable-cursor
62+
val results = collection.find<Restaurant>().cursorType(CursorType.TailableAwait)
63+
// end-tailable-cursor
64+
}
65+

source/read.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ Read Data from MongoDB
2727
/read/project
2828
/read/specify-documents-to-return
2929
/read/count
30+
/read/cursors
3031

3132
Overview
3233
--------

source/read/cursors.txt

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
.. _kotlin-sync-cursors:
2+
3+
=========================
4+
Access Data From a Cursor
5+
=========================
6+
7+
.. contents:: On this page
8+
:local:
9+
:backlinks: none
10+
:depth: 1
11+
:class: singlecol
12+
13+
.. facet::
14+
:name: genre
15+
:values: reference
16+
17+
.. meta::
18+
:keywords: read, results, oplog
19+
20+
Overview
21+
--------
22+
23+
In this guide, you can learn how to access data from a **cursor** with the
24+
{+driver-short+}.
25+
26+
A cursor is a mechanism that returns the results of a read operation in iterable
27+
batches. Because a cursor holds only a subset of documents at any given time,
28+
cursors reduce both memory consumption and network bandwidth usage.
29+
30+
Whenever the {+driver-short+} performs a read operation that returns multiple
31+
documents, it automatically returns those documents in a cursor.
32+
33+
Sample Data
34+
~~~~~~~~~~~
35+
36+
The examples in this guide use the ``restaurants`` collection in the ``sample_restaurants``
37+
database from the :atlas:`Atlas sample datasets </sample-data>`. To learn how to create a
38+
free MongoDB Atlas cluster and load the sample datasets, see the
39+
:atlas:`Get Started with Atlas </getting-started>` guide.
40+
41+
The following {+language+} data class models the documents in this collection:
42+
43+
.. literalinclude:: /includes/read/cursors.kt
44+
:start-after: start-data-class
45+
:end-before: end-data-class
46+
:language: kotlin
47+
:copyable:
48+
49+
.. _kotlin-sync-cursors-iterate:
50+
51+
Access Cursor Contents Iteratively
52+
----------------------------------
53+
54+
To iterate over the contents of a cursor, use the ``forEach()`` method, as shown in the
55+
following example:
56+
57+
.. literalinclude:: /includes/read/cursors.kt
58+
:start-after: start-cursor-iterate
59+
:end-before: end-cursor-iterate
60+
:language: kotlin
61+
:copyable:
62+
:dedent:
63+
64+
Retrieve Documents Individually
65+
-------------------------------
66+
67+
Retrieve documents from a cursor individually by calling the ``next()`` method.
68+
69+
The following example finds all documents in a collection with a ``name`` value
70+
of ``"Dunkin' Donuts"``. It then prints the first document in the cursor by calling the
71+
``next()`` method.
72+
73+
.. io-code-block::
74+
:copyable:
75+
76+
.. input:: /includes/read/cursors.kt
77+
:start-after: start-cursor-next
78+
:end-before: end-cursor-next
79+
:language: kotlin
80+
:dedent:
81+
82+
.. output::
83+
84+
Restaurant(id=5eb3d668b31de5d588f42c66, name=Dunkin' Donuts)
85+
86+
Retrieve All Documents
87+
----------------------
88+
89+
.. warning::
90+
91+
If the number and size of documents returned by your query exceeds available
92+
application memory, your program will crash. If you expect a large result
93+
set, :ref:`access your cursor iteratively <kotlin-sync-cursors-iterate>`.
94+
95+
To retrieve all documents from a cursor, convert the cursor into a ``list`` as
96+
shown in the following example:
97+
98+
.. io-code-block::
99+
:copyable:
100+
101+
.. input:: /includes/read/cursors.kt
102+
:start-after: start-cursor-list
103+
:end-before: end-cursor-list
104+
:language: kotlin
105+
:dedent:
106+
107+
.. output::
108+
109+
Restaurant(id=5eb3d668b31de5d588f42c66, name=Dunkin' Donuts)
110+
Restaurant(id=5eb3d668b31de5d588f42ca0, name=Dunkin' Donuts)
111+
Restaurant(id=5eb3d668b31de5d588f42b08, name=Dunkin' Donuts)
112+
Restaurant(id=5eb3d668b31de5d588f42cd7, name=Dunkin' Donuts)
113+
...
114+
115+
Close a Cursor
116+
--------------
117+
118+
By default, MongoDB closes a cursor when the client has exhausted all the
119+
results in the cursor. To explicitly close a cursor, call the ``close()`` method
120+
as shown in the following example:
121+
122+
.. literalinclude:: /includes/read/cursors.kt
123+
:start-after: start-cursor-close
124+
:end-before: end-cursor-close
125+
:language: kotlin
126+
:copyable:
127+
:dedent:
128+
129+
Tailable Cursors
130+
----------------
131+
132+
When querying on a :manual:`capped collection </core/capped-collections/>`, you
133+
can use a **tailable cursor** that remains open after the client exhausts the
134+
results in a cursor. To create a tailable cursor with capped collection,
135+
specify ``CursorType.TailableAwait`` to the ``cursorType`` method of a
136+
``FindIterable`` object.
137+
138+
The following example creates a tailable cursor on a collection:
139+
140+
.. literalinclude:: /includes/read/cursors.kt
141+
:start-after: start-tailable-cursor
142+
:end-before: end-tailable-cursor
143+
:language: kotlin
144+
:copyable:
145+
:dedent:
146+
147+
To learn more about tailable cursors and their usage, see the :manual:`Tailable Cursors guide
148+
</core/tailable-cursors/>` in the {+mdb-server+} manual.
149+
150+
Troubleshooting
151+
---------------
152+
153+
"*CursorNotFound* cursor id not valid at server"
154+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
155+
156+
Cursors in MongoDB can timeout on the server if they've been open for
157+
a long time without any operations being performed on them. This can
158+
lead to a ``CursorNotFound`` exception when you try to iterate through the cursor.
159+
160+
API Documentation
161+
-----------------
162+
163+
To learn more about any of the methods or types discussed in this
164+
guide, see the following API documentation:
165+
166+
- `find() <{+api+}/mongodb-driver-kotlin-sync/com.mongodb.kotlin.client/-mongo-collection/find.html>`__
167+
- `FindIterable <{+api+}/mongodb-driver-kotlin-sync/com.mongodb.kotlin.client/-find-iterable/index.html>`__
168+
- `MongoCursor <{+api+}/mongodb-driver-kotlin-sync/com.mongodb.kotlin.client/-mongo-cursor/index.html>`__
169+
- `CursorType <{+core-api+}/com/mongodb/CursorType.html>`__

0 commit comments

Comments
 (0)