Skip to content

Commit e99726e

Browse files
committed
WIP
1 parent 7f2cf49 commit e99726e

6 files changed

+180
-34
lines changed

examples/src/test/kotlin/AggregationTest.kt

+140-17
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,21 @@ import com.mongodb.client.model.Accumulators
44
import com.mongodb.client.model.Aggregates
55
import com.mongodb.client.model.Filters
66
import com.mongodb.client.model.Projections
7+
import com.mongodb.client.model.search.SearchOperator
8+
import com.mongodb.client.model.search.SearchPath.fieldPath
79
import com.mongodb.kotlin.client.coroutine.MongoClient
810
import config.getConfig
911
import kotlinx.coroutines.flow.toList
1012
import kotlinx.coroutines.runBlocking
1113
import org.bson.Document
1214
import org.bson.codecs.pojo.annotations.BsonId
15+
import org.bson.conversions.Bson
1316
import org.bson.json.JsonWriterSettings
1417
import org.junit.jupiter.api.AfterAll
1518
import org.junit.jupiter.api.BeforeAll
1619
import org.junit.jupiter.api.Test
1720
import kotlin.test.assertEquals
21+
import kotlin.test.Ignore
1822

1923

2024
class AggregationTest {
@@ -44,16 +48,102 @@ class AggregationTest {
4448
fun beforeAll() {
4549
runBlocking {
4650
val restaurants = listOf(
47-
Restaurant("Sun Bakery Trattoria", Restaurant.Contact("386-555-0189", "[email protected]", listOf(-74.0056649, 40.7452371)), 4, listOf("Pizza", "Pasta", "Italian", "Coffee", "Sandwiches")),
48-
Restaurant("Blue Bagels Grill", Restaurant.Contact("786-555-0102", "[email protected]", listOf(-73.92506, 40.8275556)), 3, listOf("Bagels", "Cookies", "Sandwiches")),
49-
Restaurant("XYZ Bagels Restaurant", Restaurant.Contact("435-555-0190", "[email protected]", listOf(-74.0707363, 40.59321569999999)), 4, listOf("Bagels", "Sandwiches", "Coffee")),
50-
Restaurant("Hot Bakery Cafe", Restaurant.Contact("264-555-0171", "[email protected]", listOf(-73.96485799999999, 40.761899)), 4, listOf("Bakery", "Cafe", "Coffee", "Dessert")),
51-
Restaurant("Green Feast Pizzeria", Restaurant.Contact("840-555-0102", "[email protected]", listOf(-74.1220973, 40.6129407)), 2, listOf("Pizza", "Italian")),
52-
Restaurant("ZZZ Pasta Buffet", Restaurant.Contact("769-555-0152", "[email protected]", listOf(-73.9446421, 40.7253944)), 0, listOf("Pasta", "Italian", "Buffet", "Cafeteria")),
53-
Restaurant("XYZ Coffee Bar", Restaurant.Contact("644-555-0193", "[email protected]", listOf(-74.0166091, 40.6284767)), 5, listOf("Coffee", "Cafe", "Bakery", "Chocolates")),
54-
Restaurant("456 Steak Restaurant", Restaurant.Contact("990-555-0165", "[email protected]", listOf(-73.9365108, 40.8497077)), 0, listOf("Steak", "Seafood")),
55-
Restaurant("456 Cookies Shop", Restaurant.Contact("604-555-0149", "[email protected]", listOf(-73.8850023, 40.7494272)), 4, listOf("Bakery", "Cookies", "Cake", "Coffee")),
56-
Restaurant("XYZ Steak Buffet", Restaurant.Contact("229-555-0197", "[email protected]", listOf(-73.9799932, 40.7660886)), 3, listOf("Steak", "Salad", "Chinese"))
51+
Restaurant(
52+
"Sun Bakery Trattoria",
53+
Restaurant.Contact(
54+
"386-555-0189",
55+
56+
listOf(-74.0056649, 40.7452371)
57+
),
58+
4,
59+
listOf("Pizza", "Pasta", "Italian", "Coffee", "Sandwiches")
60+
),
61+
Restaurant(
62+
"Blue Bagels Grill",
63+
Restaurant.Contact(
64+
"786-555-0102",
65+
66+
listOf(-73.92506, 40.8275556)
67+
),
68+
3,
69+
listOf("Bagels", "Cookies", "Sandwiches")
70+
),
71+
Restaurant(
72+
"XYZ Bagels Restaurant",
73+
Restaurant.Contact(
74+
"435-555-0190",
75+
76+
listOf(-74.0707363, 40.59321569999999)
77+
),
78+
4,
79+
listOf("Bagels", "Sandwiches", "Coffee")
80+
),
81+
Restaurant(
82+
"Hot Bakery Cafe",
83+
Restaurant.Contact(
84+
"264-555-0171",
85+
86+
listOf(-73.96485799999999, 40.761899)
87+
),
88+
4,
89+
listOf("Bakery", "Cafe", "Coffee", "Dessert")
90+
),
91+
Restaurant(
92+
"Green Feast Pizzeria",
93+
Restaurant.Contact(
94+
"840-555-0102",
95+
96+
listOf(-74.1220973, 40.6129407)
97+
),
98+
2,
99+
listOf("Pizza", "Italian")
100+
),
101+
Restaurant(
102+
"ZZZ Pasta Buffet",
103+
Restaurant.Contact(
104+
"769-555-0152",
105+
106+
listOf(-73.9446421, 40.7253944)
107+
),
108+
0,
109+
listOf("Pasta", "Italian", "Buffet", "Cafeteria")
110+
),
111+
Restaurant(
112+
"XYZ Coffee Bar",
113+
Restaurant.Contact("644-555-0193", "[email protected]", listOf(-74.0166091, 40.6284767)),
114+
5,
115+
listOf("Coffee", "Cafe", "Bakery", "Chocolates")
116+
),
117+
Restaurant(
118+
"456 Steak Restaurant",
119+
Restaurant.Contact(
120+
"990-555-0165",
121+
122+
listOf(-73.9365108, 40.8497077)
123+
),
124+
0,
125+
listOf("Steak", "Seafood")
126+
),
127+
Restaurant(
128+
"456 Cookies Shop",
129+
Restaurant.Contact(
130+
"604-555-0149",
131+
132+
listOf(-73.8850023, 40.7494272)
133+
),
134+
4,
135+
listOf("Bakery", "Cookies", "Cake", "Coffee")
136+
),
137+
Restaurant(
138+
"XYZ Steak Buffet",
139+
Restaurant.Contact(
140+
"229-555-0197",
141+
142+
listOf(-73.9799932, 40.7660886)
143+
),
144+
3,
145+
listOf("Steak", "Salad", "Chinese")
146+
)
57147
)
58148
collection.insertMany(restaurants)
59149
}
@@ -71,15 +161,17 @@ class AggregationTest {
71161
}
72162

73163
@Test
74-
fun basicAggregationTest() = runBlocking {
164+
fun basicAggregationTest() = runBlocking {
75165
// :snippet-start: basic-aggregation
76166
data class Results(@BsonId val id: Int, val count: Int)
77167

78168
val resultsFlow = collection.aggregate<Results>(
79169
listOf(
80170
Aggregates.match(Filters.eq(Restaurant::categories.name, "Bakery")),
81-
Aggregates.group("\$${Restaurant::stars.name}",
82-
Accumulators.sum("count", 1))
171+
Aggregates.group(
172+
"\$${Restaurant::stars.name}",
173+
Accumulators.sum("count", 1)
174+
)
83175
)
84176
)
85177

@@ -124,7 +216,7 @@ class AggregationTest {
124216
@Test
125217
fun explainAggregationTest() = runBlocking {
126218
// :snippet-start: explain-aggregation
127-
data class Results (val name: String, val count: Int)
219+
data class Results(val name: String, val count: Int)
128220

129221
val explanation = collection.aggregate<Results>(
130222
listOf(
@@ -143,14 +235,45 @@ class AggregationTest {
143235
@Test
144236
fun buildDocumentsTipTest() {
145237
val method1 =
146-
// :snippet-start: build-documents-tip
147-
Document("\$arrayElemAt", listOf("\$categories", 0))
238+
// :snippet-start: build-documents-tip
239+
Document("\$arrayElemAt", listOf("\$categories", 0))
148240
// is equivalent to
149241
val method2 = // :remove:
150-
Document.parse("{ \$arrayElemAt: ['\$categories', 0] }")
242+
Document.parse("{ \$arrayElemAt: ['\$categories', 0] }")
151243
// :snippet-end:
152244
// assert to test equivalency
153245
assertEquals(method1, method2)
154246

155247
}
248+
249+
/* NOTE: Test is not run by default. FTS requires the creation of a text index on the collection before running.
250+
*/
251+
@Ignore
252+
fun atlasSearchOperatorTest() = runBlocking {
253+
val collection = mongoClient.getDatabase("sample_mflix").getCollection<Document>("movies")
254+
// :snippet-start: atlas-search-pipeline
255+
val searchStage = Aggregates.search(
256+
SearchOperator.compound()
257+
.filter(
258+
listOf(
259+
SearchOperator.`in`(fieldPath("genres"), listOf("Comedy")),
260+
SearchOperator.phrase(fieldPath("fullplot"), "new york"),
261+
SearchOperator.numberRange(fieldPath("year")).gtLt(1950, 2000),
262+
SearchOperator.wildcard(fieldPath("title"), "Love *")
263+
)
264+
)
265+
)
266+
267+
val projectStage = Aggregates.project(
268+
Projections.include("title", "year", "genres", "cast"))
269+
270+
val pipeline = listOf(searchStage, projectStage)
271+
val resultsFlow = collection.aggregate(pipeline)
272+
273+
resultsFlow.collect { println(it) }
274+
// :snippet-end:
275+
276+
val result = resultsFlow.toList()
277+
assertEquals(2, result.size)
278+
}
156279
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
val searchStage = Aggregates.search(
2+
SearchOperator.compound()
3+
.filter(
4+
listOf(
5+
SearchOperator.`in`(fieldPath("genres"), listOf("Comedy")),
6+
SearchOperator.phrase(fieldPath("fullplot"), "new york"),
7+
SearchOperator.numberRange(fieldPath("year")).gtLt(1950, 2000),
8+
SearchOperator.wildcard(fieldPath("title"), "Love *")
9+
)
10+
)
11+
)
12+
13+
val projectStage = Aggregates.project(
14+
Projections.include("title", "year", "genres", "cast"))
15+
16+
val pipeline = listOf(searchStage, projectStage)
17+
val resultsFlow = collection.aggregate(pipeline)
18+
19+
resultsFlow.collect { println(it) }

source/examples/generated/AggregationTest.snippet.basic-aggregation.kt

+4-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ data class Results(@BsonId val id: Int, val count: Int)
33
val resultsFlow = collection.aggregate<Results>(
44
listOf(
55
Aggregates.match(Filters.eq(Restaurant::categories.name, "Bakery")),
6-
Aggregates.group("\$${Restaurant::stars.name}",
7-
Accumulators.sum("count", 1))
6+
Aggregates.group(
7+
"\$${Restaurant::stars.name}",
8+
Accumulators.sum("count", 1)
9+
)
810
)
911
)
1012

Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
Document("\$arrayElemAt", listOf("\$categories", 0))
1+
Document("\$arrayElemAt", listOf("\$categories", 0))
22
// is equivalent to
3-
Document.parse("{ \$arrayElemAt: ['\$categories', 0] }")
3+
Document.parse("{ \$arrayElemAt: ['\$categories', 0] }")

source/examples/generated/AggregationTest.snippet.explain-aggregation.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
data class Results (val name: String, val count: Int)
1+
data class Results(val name: String, val count: Int)
22

33
val explanation = collection.aggregate<Results>(
44
listOf(

source/fundamentals/aggregation.txt

+14-12
Original file line numberDiff line numberDiff line change
@@ -225,30 +225,32 @@ Search provides ``$search`` and ``$searchMeta`` stages, both of which must be th
225225
stage in any query pipeline. For more information about Atlas pipeline stages,
226226
see the :atlas:`Choose the Aggregation Pipeline Stage
227227
</atlas-search/query-syntax/>` page in the Atlas
228-
manual.
228+
manual.
229+
230+
.. tip:: Aggregates Builders
231+
232+
This example in this section uses helper methods from the
233+
:ref:`Aggregates <aggregates-builders>` builder class.
229234

230235
.. sharedinclude:: dbx/jvm/atlas-search-operator-helpers.rst
231236

237+
.. replacement:: as-idx-link
238+
239+
the :ref:`kotlin-search-indexes` section of the Indexes guide
240+
232241
.. replacement:: atlas-query-operators-example
233242

234243
.. io-code-block::
235244

236-
.. input:: /examples/atlas-examples/AtlasSearchHelpers.kt
245+
.. input:: /examples/generated/AggregationTest.snippet.atlas-search-pipeline.kt
237246
:language: kotlin
238-
:start-after: // start atlasHelperMethods
239-
:end-before: // end atlasHelperMethods
240-
:dedent:
241247

242248
.. output::
243249
:language: console
244250
:visible: false
245251

246-
Document{{_id=573a1397f29313caabce86db, genres=[Drama, Sport], cast=[Sylvester Stallone, Talia Shire, Burt Young, Carl Weathers], title=Rocky III, year=1982}}
247-
Document{{_id=573a1398f29313caabce9af0, genres=[Drama, Sport], cast=[Sylvester Stallone, Talia Shire, Burt Young, Carl Weathers], title=Rocky IV, year=1985}}
248-
249-
.. replacement:: searchoperator-interface-api-docs
250-
251-
the `SearchOperator Interface API documentation <{+core-api+}/client/model/search/SearchOperator.html>`__
252+
Document{{_id=573a1397f29313caabce734c, genres=[Comedy, Romance], cast=[George Hamilton, Susan Saint James, Richard Benjamin, Dick Shawn], title=Love at First Bite, year=1979}}
253+
Document{{_id=573a1399f29313caabcee81e, genres=[Comedy, Drama], cast=[Warren Beatty, Annette Bening, Katharine Hepburn, Garry Shandling], title=Love Affair, year=1994}}
252254

253255
API Documentation
254256
-----------------
@@ -260,4 +262,4 @@ see the following API Documentation:
260262
- `$group <{+core-api+}/client/model/Aggregates.html#group(TExpression,java.util.List)>`__
261263
- `$project <{+core-api+}/client/model/Aggregates.html#project(org.bson.conversions.Bson)>`__
262264
- `Projections <{+core-api+}/client/model/Projections.html>`__
263-
- `SearchOperator Interface <{+core-api+}/com/mongodb/client/model/search/SearchOperator.html>`__
265+
- `SearchOperator <{+core-api+}/com/mongodb/client/model/search/SearchOperator.html>`__

0 commit comments

Comments
 (0)