Skip to content

Commit a151366

Browse files
authored
(DOCSP-29186): CRUD > Sort Results page (#19)
* (DOCSP-29186): CRUD > Sort Results page * Remove unnecessary import examples * remove sync dependency * Apply initial internal feedback * Convert to Flow.collect { } * Fix text search code example * Apply review feedback * Apply review feedback * Small fixes * Fix link * Update misses * Apply feedback
1 parent 7fa3ffd commit a151366

13 files changed

+368
-156
lines changed

examples/build.gradle.kts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ dependencies {
2020
testImplementation(kotlin("test"))
2121
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.0-Beta")
2222
implementation("org.mongodb:mongodb-driver-kotlin-coroutine:4.10.0-SNAPSHOT")
23-
implementation("org.mongodb:mongodb-driver-core:4.10.0-SNAPSHOT")
2423
implementation("org.slf4j:slf4j-api:1.7.32")
2524
implementation("ch.qos.logback:logback-classic:1.2.6")
2625
implementation("io.github.cdimascio:dotenv-kotlin:6.4.1")

examples/src/test/kotlin/SortTest.kt

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
2+
import com.mongodb.client.model.*
3+
import com.mongodb.client.model.Sorts.*
4+
import com.mongodb.kotlin.client.coroutine.MongoClient
5+
import io.github.cdimascio.dotenv.dotenv
6+
import kotlinx.coroutines.flow.toList
7+
import kotlinx.coroutines.runBlocking
8+
import org.bson.codecs.pojo.annotations.BsonId
9+
import org.junit.jupiter.api.AfterAll
10+
import org.junit.jupiter.api.Assertions.*
11+
import org.junit.jupiter.api.BeforeAll
12+
import org.junit.jupiter.api.TestInstance
13+
import java.util.*
14+
import kotlin.test.*
15+
16+
17+
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
18+
internal class SortTest {
19+
20+
companion object {
21+
// :snippet-start: sort-data-model
22+
data class FoodOrder(
23+
@BsonId val id: Int,
24+
val letter: String,
25+
val food: String
26+
)
27+
// :snippet-end:
28+
29+
val dotenv = dotenv()
30+
val client = MongoClient.create(dotenv["MONGODB_CONNECTION_URI"])
31+
val database = client.getDatabase("cafe")
32+
val collection = database.getCollection<FoodOrder>("food_order")
33+
34+
@BeforeAll
35+
@JvmStatic
36+
private fun beforeAll() {
37+
runBlocking {
38+
val foodOrders = listOf(
39+
FoodOrder(1, "c", "coffee with milk"),
40+
FoodOrder(3, "a", "maple syrup"),
41+
FoodOrder(4, "b", "coffee with sugar"),
42+
FoodOrder(5, "a", "milk and cookies"),
43+
FoodOrder(2, "a", "donuts and coffee"),
44+
FoodOrder(6, "c", "maple donut")
45+
)
46+
collection.insertMany(foodOrders)
47+
}
48+
}
49+
50+
@AfterAll
51+
@JvmStatic
52+
private fun afterAll() {
53+
runBlocking {
54+
collection.drop()
55+
client.close()
56+
}
57+
}
58+
}
59+
60+
@Test
61+
fun basicSortTest() = runBlocking {
62+
// :snippet-start: basic-sort
63+
collection.find().sort(Sorts.ascending("_id"))
64+
// :snippet-end:
65+
// Junit test for the above code
66+
val filter = Filters.empty()
67+
val expected = listOf(
68+
FoodOrder(1, "c", "coffee with milk"),
69+
FoodOrder(2, "a", "donuts and coffee"),
70+
FoodOrder(3, "a", "maple syrup"),
71+
FoodOrder(4, "b", "coffee with sugar"),
72+
FoodOrder(5, "a", "milk and cookies"),
73+
FoodOrder(6, "c", "maple donut")
74+
75+
)
76+
assertEquals(expected, collection.find(filter).sort((ascending("_id"))).toList() )
77+
}
78+
79+
@Test
80+
fun aggregationSortTest() = runBlocking {
81+
// :snippet-start: aggregation-sort
82+
val resultsFlow = collection.aggregate(listOf(
83+
Aggregates.sort(Sorts.ascending("_id"))
84+
))
85+
resultsFlow.collect { println(it) }
86+
// :snippet-end:
87+
// Junit test for the above code
88+
val expected = listOf(
89+
FoodOrder(1, "c", "coffee with milk"),
90+
FoodOrder(2, "a", "donuts and coffee"),
91+
FoodOrder(3, "a", "maple syrup"),
92+
FoodOrder(4, "b", "coffee with sugar"),
93+
FoodOrder(5, "a", "milk and cookies"),
94+
FoodOrder(6, "c", "maple donut")
95+
)
96+
assertEquals(expected, resultsFlow.toList())
97+
}
98+
99+
@Test
100+
fun ascendingSortTest() = runBlocking {
101+
// :snippet-start: ascending-sort
102+
val resultsFlow = collection.find()
103+
.sort(Sorts.ascending("_id"))
104+
resultsFlow.collect { println(it) }
105+
// :snippet-end:
106+
// Junit test for the above code
107+
val expected = listOf(
108+
FoodOrder(1, "c", "coffee with milk"),
109+
FoodOrder(2, "a", "donuts and coffee"),
110+
FoodOrder(3, "a", "maple syrup"),
111+
FoodOrder(4, "b", "coffee with sugar"),
112+
FoodOrder(5, "a", "milk and cookies"),
113+
FoodOrder(6, "c", "maple donut")
114+
)
115+
assertEquals(expected, resultsFlow.toList())
116+
}
117+
118+
@Test
119+
fun descendingSortTest() = runBlocking {
120+
// :snippet-start: descending-sort
121+
val resultsFlow = collection.find()
122+
.sort(Sorts.descending("_id"))
123+
resultsFlow.collect { println(it) }
124+
// :snippet-end:
125+
// Junit test for the above code
126+
val expected = listOf(
127+
FoodOrder(6, "c", "maple donut"),
128+
FoodOrder(5, "a", "milk and cookies"),
129+
FoodOrder(4, "b", "coffee with sugar"),
130+
FoodOrder(3, "a", "maple syrup"),
131+
FoodOrder(2, "a", "donuts and coffee"),
132+
FoodOrder(1, "c", "coffee with milk")
133+
)
134+
assertEquals(expected, resultsFlow.toList())
135+
}
136+
137+
@Test
138+
fun handleTiesTest() = runBlocking {
139+
// :snippet-start: handle-ties-1
140+
collection.find().sort(Sorts.ascending(FoodOrder::letter.name))
141+
// :snippet-end:
142+
val results =
143+
// :snippet-start: handle-ties-2
144+
collection.find().sort(Sorts.ascending(FoodOrder::letter.name, "_id"))
145+
// :snippet-end:
146+
// Junit test for the above code
147+
val filter = Filters.empty()
148+
val expected = listOf(
149+
FoodOrder(2, "a", "donuts and coffee"),
150+
FoodOrder(3, "a", "maple syrup"),
151+
FoodOrder(5, "a", "milk and cookies"),
152+
FoodOrder(4, "b", "coffee with sugar"),
153+
FoodOrder(1, "c", "coffee with milk"),
154+
FoodOrder(6, "c", "maple donut")
155+
)
156+
assertEquals(expected, results.toList() )
157+
}
158+
159+
@Test
160+
fun combineSortTest() = runBlocking {
161+
// :snippet-start: combine-sort
162+
val orderBySort = Sorts.orderBy(
163+
Sorts.descending(FoodOrder::letter.name), ascending("_id")
164+
)
165+
val results = collection.find().sort(orderBySort)
166+
results.collect {println(it) }
167+
// :snippet-end:
168+
// Junit test for the above code
169+
val filter = Filters.empty()
170+
val expected = listOf(
171+
FoodOrder(1, "c", "coffee with milk"),
172+
FoodOrder(6, "c", "maple donut"),
173+
FoodOrder(4, "b", "coffee with sugar"),
174+
FoodOrder(2, "a", "donuts and coffee"),
175+
FoodOrder(3, "a", "maple syrup"),
176+
FoodOrder(5, "a", "milk and cookies")
177+
)
178+
assertEquals(expected, results.toList() )
179+
}
180+
181+
@Test
182+
fun textSearchTest() = runBlocking {
183+
// :snippet-start: food-order-score
184+
data class FoodOrderScore(
185+
@BsonId val id: Int,
186+
val letter: String,
187+
val food: String,
188+
val score: Double
189+
)
190+
// :snippet-end:
191+
// :snippet-start: text-search
192+
collection.createIndex(Indexes.text(FoodOrderScore::food.name))
193+
val metaTextScoreSort = Sorts.orderBy(
194+
Sorts.metaTextScore(FoodOrderScore::score.name),
195+
Sorts.descending("_id")
196+
)
197+
val metaTextScoreProj = Projections.metaTextScore(FoodOrderScore::score.name)
198+
val searchTerm = "maple donut"
199+
val searchQuery = Filters.text(searchTerm)
200+
201+
val results = collection.find<FoodOrderScore>(searchQuery)
202+
.projection(metaTextScoreProj)
203+
.sort(metaTextScoreSort)
204+
205+
results.collect { println(it) }
206+
// :snippet-end:
207+
// Junit test for the above code
208+
val expected = listOf(
209+
FoodOrderScore(6, "c", "maple donut",1.5),
210+
FoodOrderScore(3, "a", "maple syrup", 0.75),
211+
FoodOrderScore(2, "a", "donuts and coffee", 0.75),
212+
)
213+
assertEquals(expected, results.toList())
214+
}
215+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
val resultsFlow = collection.aggregate(listOf(
2+
Aggregates.sort(Sorts.ascending("_id"))
3+
))
4+
resultsFlow.collect { println(it) }
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
val resultsFlow = collection.find()
2+
.sort(Sorts.ascending("_id"))
3+
resultsFlow.collect { println(it) }
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
collection.find().sort(Sorts.ascending("_id"))
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
val orderBySort = Sorts.orderBy(
2+
Sorts.descending(FoodOrder::letter.name), ascending("_id")
3+
)
4+
val results = collection.find().sort(orderBySort)
5+
results.collect {println(it) }
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
val resultsFlow = collection.find()
2+
.sort(Sorts.descending("_id"))
3+
resultsFlow.collect { println(it) }
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
data class FoodOrderScore(
2+
@BsonId val id: Int,
3+
val letter: String,
4+
val food: String,
5+
val score: Double
6+
)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
collection.find().sort(Sorts.ascending(FoodOrder::letter.name))
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
collection.find().sort(Sorts.ascending(FoodOrder::letter.name, "_id"))

0 commit comments

Comments
 (0)