1
+ import com.mongodb.kotlin.client.model.Aggregates.count
2
+ import com.mongodb.client.model.Aggregates.group
3
+ import com.mongodb.client.model.Aggregates.limit
4
+ import com.mongodb.client.model.Aggregates.sort
5
+ import com.mongodb.kotlin.client.coroutine.MongoClient
6
+ import config.getConfig
7
+ import kotlinx.coroutines.flow.firstOrNull
8
+ import kotlinx.coroutines.runBlocking
9
+ import org.junit.jupiter.api.AfterAll
10
+ import org.junit.jupiter.api.AfterEach
11
+ import org.junit.jupiter.api.Assertions
12
+ import org.junit.jupiter.api.Test
13
+ import org.junit.jupiter.api.TestInstance
14
+
15
+ import com.mongodb.kotlin.client.model.Filters.eq
16
+ import com.mongodb.kotlin.client.model.Filters.all
17
+ import com.mongodb.kotlin.client.model.Indexes
18
+ import com.mongodb.kotlin.client.model.Projections.excludeId
19
+ import com.mongodb.kotlin.client.model.Projections.fields
20
+ import com.mongodb.kotlin.client.model.Projections.include
21
+ import com.mongodb.client.model.Sorts.orderBy
22
+ import com.mongodb.kotlin.client.model.Accumulators.avg
23
+ import com.mongodb.kotlin.client.model.Sorts
24
+
25
+ import com.mongodb.kotlin.client.model.Filters.gte
26
+ import com.mongodb.kotlin.client.model.Updates.addToSet
27
+ import com.mongodb.kotlin.client.model.Updates.combine
28
+ import com.mongodb.kotlin.client.model.Updates.max
29
+ import kotlin.test.assertEquals
30
+ import kotlin.test.assertTrue
31
+
32
+ @TestInstance(TestInstance .Lifecycle .PER_CLASS )
33
+ internal class BuildersDataClassTest {
34
+
35
+ companion object {
36
+ val config = getConfig()
37
+ val client = MongoClient .create(config.connectionUri)
38
+ val database = client.getDatabase(" school" )
39
+
40
+ @AfterAll
41
+ @JvmStatic
42
+ fun afterAll () {
43
+ runBlocking {
44
+ client.close()
45
+ }
46
+ }
47
+ }
48
+
49
+ @AfterEach
50
+ fun afterEach () {
51
+ runBlocking {
52
+ database.drop()
53
+ }
54
+ }
55
+
56
+ // :snippet-start: data-class
57
+ data class Student (
58
+ val name : String ,
59
+ val teachers : List <String >,
60
+ val gradeAverage : Double
61
+ )
62
+ // :snippet-end:
63
+
64
+
65
+ @Test
66
+ fun filtersTest () = runBlocking {
67
+
68
+ val collection = database.getCollection<Student >(" students" )
69
+
70
+ // :snippet-start: filters-data-class
71
+ val student = Student (
72
+ " Sandra Nook" ,
73
+ listOf (" Alvarez" , " Gruber" ),
74
+ 85.7
75
+ )
76
+
77
+ // Equivalent equality queries
78
+ Student ::name.eq(student.name)
79
+ eq(Student ::name, student.name)
80
+ Student ::name eq student.name // Infix notation
81
+
82
+ // Equivalent array queries
83
+ all(Student ::teachers, student.teachers)
84
+ Student ::teachers.all(student.teachers)
85
+ Student ::teachers all student.teachers // Infix notation
86
+ // :snippet-end:
87
+
88
+ collection.insertOne(student)
89
+ val filter = eq(Student ::name, student.name)
90
+ val result = collection.find(filter).firstOrNull()
91
+ Assertions .assertEquals(student, result)
92
+ }
93
+
94
+ @Test
95
+ fun indexesTest () = runBlocking {
96
+
97
+ val collection = database.getCollection<Student >(" students" )
98
+
99
+ // :snippet-start: indexes-data-class
100
+ val ascendingIdx = Indexes .ascending(Student ::name)
101
+ val descendingIdx = Indexes .descending(Student ::teachers)
102
+
103
+ val ascIdxName = collection.createIndex(ascendingIdx)
104
+ val descIdxName = collection.createIndex(descendingIdx)
105
+ // :snippet-end:
106
+
107
+ assertEquals(" name_1" , ascIdxName)
108
+ }
109
+
110
+ @Test
111
+ fun projectionsTest () = runBlocking {
112
+
113
+ val collection = database.getCollection<Student >(" students" )
114
+
115
+ val student = Student (
116
+ " Sandra Nook" ,
117
+ listOf (" Alvarez" , " Gruber" ),
118
+ 85.7
119
+ )
120
+ collection.insertOne(student)
121
+
122
+ // :snippet-start: projections-data-class
123
+ val combinedProj = fields(
124
+ include(Student ::name, Student ::gradeAverage),
125
+ excludeId()
126
+ )
127
+
128
+ collection.find().projection(combinedProj)
129
+ // :snippet-end:
130
+
131
+ data class Result (val name : String , val gradeAverage : Double )
132
+ val result = collection.find<Result >().projection(combinedProj).firstOrNull()
133
+
134
+ if (result != null ) {
135
+ assertEquals(85.7 , result.gradeAverage)
136
+ }
137
+ }
138
+
139
+ @Test
140
+ fun sortsTest () = runBlocking {
141
+
142
+ val collection = database.getCollection<Student >(" students" )
143
+
144
+ val student1 = Student (
145
+ " Sandra Nook" ,
146
+ listOf (" Alvarez" , " Gruber" ),
147
+ 85.7
148
+ )
149
+ val student2 = Student (
150
+ " Paolo Sanchez" ,
151
+ listOf (" Gruber" , " Piselli" ),
152
+ 89.3
153
+ )
154
+ collection.insertMany(listOf (student1, student2))
155
+
156
+ // :snippet-start: sorts-data-class
157
+ val sort = orderBy(
158
+ Sorts .descending(Student ::gradeAverage),
159
+ Sorts .ascending(Student ::name)
160
+ )
161
+
162
+ collection.find().sort(sort)
163
+ // :snippet-end:
164
+
165
+ val result = collection.find().sort(sort).firstOrNull()
166
+
167
+ if (result != null ) {
168
+ assertEquals(89.3 , result.gradeAverage)
169
+ }
170
+ }
171
+
172
+ @Test
173
+ fun updatesTest () = runBlocking {
174
+
175
+ val collection = database.getCollection<Student >(" students" )
176
+
177
+ val students = listOf (
178
+ Student (" Sandra Nook" , listOf (" Alvarez" , " Gruber" ),85.7 ),
179
+ Student (" Paolo Sanchez" , listOf (" Gruber" , " Piselli" ),89.3 )
180
+ )
181
+ collection.insertMany(students)
182
+
183
+ // :snippet-start: updates-data-class
184
+ val filter = Student ::gradeAverage gte 85.0
185
+ val update = combine(
186
+ addToSet(Student ::teachers, " Soto" ),
187
+ Student ::gradeAverage.max(90.0 )
188
+ )
189
+ collection.updateMany(filter, update)
190
+ // :snippet-end:
191
+
192
+ val result = collection.find().firstOrNull()
193
+
194
+ if (result != null ) {
195
+ assertTrue(" Soto" in result.teachers)
196
+ assertEquals(result.gradeAverage, 90.0 )
197
+ }
198
+ }
199
+
200
+ @Test
201
+ fun aggregatesTest () = runBlocking {
202
+
203
+ val collection = database.getCollection<Student >(" students" )
204
+
205
+ val students = listOf (
206
+ Student (" Sandra Nook" , listOf (" Alvarez" , " Gruber" ),85.7 ),
207
+ Student (" Paolo Sanchez" , listOf (" Gruber" , " Piselli" ),89.3 ),
208
+ Student (" Katerina Jakobsen" , listOf (" Alvarez" , " Ender" ),97.3 ),
209
+ Student (" Emma Frank" , listOf (" Piselli" , " Harbour" ),93.4 ),
210
+ Student (" Qasim Haq" , listOf (" Gruber" , " Harbour" ),80.6 )
211
+ )
212
+ collection.insertMany(students)
213
+
214
+ // :snippet-start: aggregates-data-class
215
+ // Data class to store aggregation result
216
+ data class Summary ( val average : Double )
217
+
218
+ val pipeline = listOf (
219
+ // Sorts grades from high to low
220
+ sort(Sorts .descending(Student ::gradeAverage)),
221
+ // Selects the top 3 students
222
+ limit(3 ),
223
+ // Calculates the average of their grades and stores value in a Summary instance
224
+ group(null , avg(Summary ::average, " \$ ${Student ::gradeAverage.name} " ))
225
+ )
226
+
227
+ val result = collection.aggregate<Summary >(pipeline)
228
+ // :snippet-end:
229
+
230
+ val r = result.firstOrNull()
231
+ if (r != null ) {
232
+ assertEquals(93.33333333333333 , r.average)
233
+ }
234
+ }
235
+
236
+ @Test
237
+ fun aggregatesCountTest () = runBlocking {
238
+
239
+ val collection = database.getCollection<Student >(" students" )
240
+
241
+ val students = listOf (
242
+ Student (" Sandra Nook" , listOf (" Alvarez" , " Gruber" ),85.7 ),
243
+ Student (" Paolo Sanchez" , listOf (" Gruber" , " Piselli" ),89.3 ),
244
+ )
245
+ collection.insertMany(students)
246
+
247
+ // :snippet-start: aggregates-data-class
248
+ val pipeline = listOf (
249
+ count(Student ::name)
250
+ )
251
+
252
+ val result = collection.aggregate(pipeline)
253
+ result.collect { println (it) }
254
+ // :snippet-end:
255
+ }
256
+ }
0 commit comments