Skip to content

Commit 86063c0

Browse files
authored
(DOCSP-29211): CRUD > Limit the Number of Returned Results page (#27)
* (DOCSP-29211): CRUD > Specify a Limit page * Fix code snippets * Refactor as data class and apply review feedback * Optimize imports * Convert to Flow.collect { } * Delete unneeded snippet
1 parent a708aa6 commit 86063c0

File tree

6 files changed

+172
-79
lines changed

6 files changed

+172
-79
lines changed

examples/src/test/kotlin/LimitTest.kt

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import com.mongodb.client.model.Sorts.descending
2+
import com.mongodb.kotlin.client.coroutine.MongoClient
3+
import io.github.cdimascio.dotenv.dotenv
4+
import kotlinx.coroutines.flow.toList
5+
import kotlinx.coroutines.runBlocking
6+
import org.bson.codecs.pojo.annotations.BsonId
7+
import org.junit.jupiter.api.AfterAll
8+
import org.junit.jupiter.api.Assertions.*
9+
import org.junit.jupiter.api.BeforeAll
10+
import org.junit.jupiter.api.TestInstance
11+
import kotlin.test.*
12+
13+
// :snippet-start: data-model
14+
data class Book(
15+
@BsonId val id: Int,
16+
val title: String,
17+
val author: String,
18+
val length: Int
19+
)
20+
// :snippet-end:
21+
22+
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
23+
internal class LimitTest {
24+
25+
companion object {
26+
val dotenv = dotenv()
27+
val client = MongoClient.create(dotenv["MONGODB_CONNECTION_URI"])
28+
val database = client.getDatabase("library")
29+
val collection = database.getCollection<Book>("books")
30+
31+
@BeforeAll
32+
@JvmStatic
33+
private fun beforeAll() {
34+
runBlocking {
35+
val books = listOf(
36+
Book(1, "The Brothers Karamazov", "Dostoyevsky", 824),
37+
Book(2, "Les Misérables", "Hugo", 1462),
38+
Book(3, "Atlas Shrugged", "Rand", 1088),
39+
Book(4,"Infinite Jest", "Wallace", 1104),
40+
Book(5, "Cryptonomicon", "Stephenson", 918),
41+
Book(6, "A Dance with Dragons", "Martin", 1104)
42+
)
43+
collection.insertMany(books)
44+
}
45+
}
46+
47+
@AfterAll
48+
@JvmStatic
49+
private fun afterAll() {
50+
runBlocking {
51+
collection.drop()
52+
client.close()
53+
}
54+
}
55+
}
56+
57+
@Test
58+
fun specifyLimitTest() = runBlocking {
59+
// :snippet-start: specify-limit
60+
val results = collection.find()
61+
.sort(descending("length"))
62+
.limit(3)
63+
results.collect { println(it) }
64+
// :snippet-end:
65+
// Junit test for the above code
66+
val expectation = listOf(
67+
Book(2, "Les Misérables", "Hugo", 1462),
68+
Book(6, "A Dance with Dragons", "Martin", 1104),
69+
Book(4, "Infinite Jest", "Wallace", 1104)
70+
)
71+
assertEquals(expectation, results.toList())
72+
}
73+
74+
@Test
75+
fun combineSkipLimitTest() = runBlocking {
76+
// :snippet-start: skip-limit
77+
val results = collection.find()
78+
.sort(descending("length"))
79+
.skip(3)
80+
.limit(3)
81+
results.collect { println(it) }
82+
// :snippet-end:
83+
// Junit test for the above code
84+
val expectation = listOf(
85+
Book(3, "Atlas Shrugged", "Rand", 1088),
86+
Book(5, "Cryptonomicon", "Stephenson", 918),
87+
Book(1, "The Brothers Karamazov", "Dostoyevsky", 824)
88+
)
89+
assertEquals(expectation, results.toList())
90+
}
91+
92+
@Test
93+
fun equivalenceTest() = runBlocking {
94+
// :snippet-start: equivalent
95+
val results = // :remove:
96+
collection.find().sort(descending("length")).limit(3)
97+
.toList() // :remove:
98+
val results2 = // :remove:
99+
collection.find().limit(3).sort(descending("length"))
100+
// :snippet-end:
101+
.toList()
102+
assertEquals(results,results2)
103+
104+
}
105+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
data class Book(
2+
@BsonId val id: Int,
3+
val title: String,
4+
val author: String,
5+
val length: Int
6+
)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
collection.find().sort(descending("length")).limit(3)
2+
collection.find().limit(3).sort(descending("length"))
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
val results = collection.find()
2+
.sort(descending("length"))
3+
.skip(3)
4+
.limit(3)
5+
results.collect { println(it) }
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
val results = collection.find()
2+
.sort(descending("length"))
3+
.limit(3)
4+
results.collect { println(it) }

source/fundamentals/crud/read-operations/limit.txt

Lines changed: 50 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Overview
1616
--------
1717

1818
In this guide, you can learn how to limit the number of results returned
19-
from read operations with the MongoDB Java driver.
19+
from read operations with the MongoDB Kotlin driver.
2020

2121
Use ``limit()`` to cap the number of documents that a read operation returns.
2222
This instance method designates the maximum number of
@@ -34,102 +34,73 @@ and how to combine ``limit()`` with ``skip()`` to further narrow the results ret
3434
Sample Documents
3535
~~~~~~~~~~~~~~~~
3636

37-
The following operation inserts documents representing books into a collection:
38-
39-
.. code-block:: java
40-
41-
collection.insertMany(Arrays.asList(
42-
new Document().append("_id", 1)
43-
.append("title", "The Brothers Karamazov").append("length", 824)
44-
.append("author", "Dostoyevsky"),
45-
new Document().append("_id", 2)
46-
.append("title", "Les Misérables").append("length", 1462).append("author", "Hugo"),
47-
new Document().append("_id", 3)
48-
.append("title", "Atlas Shrugged").append("length", 1088).append("author", "Rand"),
49-
new Document().append("_id", 4)
50-
.append("title", "Infinite Jest").append("length", 1104).append("author", "Wallace"),
51-
new Document().append("_id", 5)
52-
.append("title", "Cryptonomicon").append("length", 918).append("author", "Stephenson"),
53-
new Document().append("_id", 6)
54-
.append("title", "A Dance with Dragons").append("length", 1104)
55-
.append("author", "Martin")
56-
));
37+
The following sections feature examples that update this sample document:
38+
39+
.. code-block:: json
40+
41+
{ "_id": 1, "title": "The Brothers Karamazov", "author": "Dostoyevsky", "length": 824 }
42+
{ "_id": 2, "title": "Les Misérables", "author": "Hugo", "length": 1462 }
43+
{ "_id": 3, "title": "Atlas Shrugged", "author": "Rand", "length": 1088 }
44+
{ "_id": 4, "title": "Infinite Jest", "author": "Wallace", "length": 1104 }
45+
{ "_id": 5, "title": "Cryptonomicon", "author": "Stephenson", "length": 918 }
46+
{ "_id": 6, "title": "A Dance with Dragons", "author": "Martin", "length": 1104 }
47+
48+
This data is modeled with the following Kotlin data class:
49+
50+
.. literalinclude:: /examples/generated/LimitTest.snippet.data-model.kt
51+
:language: kotlin
5752

5853
Specify a Limit
5954
---------------
6055

6156
The next example queries the collection to return the top three
6257
longest books. It first matches all the documents with the query, then sorts on the
6358
``length`` field to return books with longer lengths before
64-
books with shorter lengths. Lastly, it limits the return value to ``3`` documents:
65-
66-
.. code-block:: java
67-
:emphasize-lines: 6
68-
69-
import com.mongodb.client.model.Sorts;
70-
71-
// define a cursor that will return the first 3 sorted items
72-
MongoCursor<Document> cursor = collection.find()
73-
.sort(descending("length"))
74-
.limit(3)
75-
.iterator();
76-
// print out items
77-
try {
78-
while (cursor.hasNext()) {
79-
System.out.println(cursor.next());
80-
}
81-
}
82-
// close the cursor
83-
finally {
84-
cursor.close();
85-
}
86-
87-
The preceding code example prints out the following three documents, sorted by
88-
length:
89-
90-
.. code-block:: java
91-
:copyable: false
92-
93-
Document{{_id=2, title=Les Misérables, author=Hugo, length=1462}}
94-
Document{{_id=6, title=A Dance with Dragons, author=Martin, length=1104}}
95-
Document{{_id=4, title=Infinite Jest, author=Wallace, length=1104}}
59+
books with shorter lengths. Lastly, it limits the return value to ``3`` documents,
60+
and returns the following three documents, sorted by length:
61+
62+
.. io-code-block::
63+
64+
.. input:: /examples/generated/LimitTest.snippet.specify-limit.kt
65+
:language: kotlin
66+
:emphasize-lines: 3
67+
68+
.. output::
69+
:language: console
70+
71+
Book(id=2, title=Les Misérables, author=Hugo, length=1462)
72+
Book(id=6, title=A Dance with Dragons, author=Martin, length=1104)
73+
Book(id=4, title=Infinite Jest, author=Wallace, length=1104)
9674

9775
.. tip::
9876

9977
The order in which you call ``limit()`` and ``sort()`` does not matter
100-
because the driver reorders the calls to apply the sort first and the
78+
because the find command always applies the sort first and the
10179
limit after it. The following two calls are equivalent:
10280

103-
.. code-block:: java
104-
105-
collection.find().sort(descending("length")).limit(3);
106-
collection.find().limit(3).sort(descending("length"));
81+
.. literalinclude:: /examples/generated/LimitTest.snippet.equivalent.kt
82+
:language: kotlin
10783

10884
Combining Skip and Limit
10985
------------------------
11086

11187
To see the next three longest books, append the ``skip()`` method to your
11288
``find()`` call. The integer argument passed to ``skip()`` will determine
113-
how many documents the find operation returns:
114-
115-
.. code-block:: java
116-
:emphasize-lines: 3, 4
89+
how many documents the find operation returns. This operation returns the
90+
documents that describe the fourth through sixth longest books:
11791

118-
MongoCursor<Document> cursor = collection.find()
119-
.sort(ascending("length"))
120-
.limit(3)
121-
.skip(3)
122-
.iterator();
92+
.. io-code-block::
12393

124-
This operation returns the documents that describe the fourth through sixth
125-
longest books:
94+
.. input:: /examples/generated/LimitTest.snippet.skip-limit.kt
95+
:language: kotlin
96+
:emphasize-lines: 3, 4
12697

127-
.. code-block:: java
128-
:copyable: false
98+
.. output::
99+
:language: console
129100

130-
Document{{_id=3, title=Atlas Shrugged, author=Rand, length=1088}}
131-
Document{{_id=5, title=Cryptonomicon, author=Stephenson, length=918}}
132-
Document{{_id=1, title=The Brothers Karamazov, author=Dostoyevsky, length=824}}
101+
Book(id=3, title=Atlas Shrugged, author=Rand, length=1088)
102+
Book(id=5, title=Cryptonomicon, author=Stephenson, length=918)
103+
Book(id=1, title=The Brothers Karamazov, author=Dostoyevsky, length=824)
133104

134105
You can combine ``skip()`` and ``limit()`` in this way to implement paging for your
135106
collection, returning only small subsets of the collection at one time.
@@ -143,7 +114,7 @@ collection, returning only small subsets of the collection at one time.
143114

144115
For example, consider the following data:
145116

146-
.. code-block:: java
117+
.. code-block:: json
147118
:copyable: false
148119

149120
{ type: "computer", data: "1", serial_no: 235235 }
@@ -159,7 +130,7 @@ collection, returning only small subsets of the collection at one time.
159130
For more information about the methods and classes mentioned in this guide,
160131
see the following API Documentation:
161132

162-
- `FindIterable <{+api+}/apidocs/mongodb-driver-sync/com/mongodb/client/FindIterable.html>`__
163-
- `MongoIterable <{+api+}/apidocs/mongodb-driver-sync/com/mongodb/client/MongoIterable.html>`__
164-
- `MongoCursor <{+api+}/apidocs/mongodb-driver-sync/com/mongodb/client/MongoCursor.html>`__
165-
- `find() <{+api+}/apidocs/mongodb-driver-sync/com/mongodb/client/MongoCollection.html#find()>`__
133+
- `FindIterable <TODO:(DOCSP-29169)>`__
134+
- `MongoIterable <TODO:(DOCSP-29169)>`__
135+
- `MongoCursor <TODO:(DOCSP-29169)>`__
136+
- `find() <TODO:(DOCSP-29169)>`__

0 commit comments

Comments
 (0)