8000 [Kotlin CR] Add additional SearchOperator helper methods for the rest… · mongodb/docs-kotlin@05b26be · GitHub
[go: up one dir, main page]

Skip to content

Commit 05b26be

Browse files
[Kotlin CR] Add additional SearchOperator helper methods for the rest of the Atlas Search operators (#208)
* atlas searchoperation helper methods * fix link * eg * ref link * WIP * moved the file to examples dir * WIP * WIP * WIP * WIP --------- Co-authored-by: rustagir <rea.rustagi@mongodb.com> Co-authored-by: Rea Rustagi <85902999+rustagir@users.noreply.github.com>
1 parent 31ef612 commit 05b26be

10 files changed

+208
-24
lines changed

examples/src/test/kotlin/AggregatesBuilderTest.kt

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ class AggregatesBuilderTest {
5757
val rated: String,
5858
val plot: String,
5959
val runtime: Int,
60-
val imdb: IMDB
60+
val imdb: IMDB,
61+
val fullplot: String? = "No full plot",
6162
){
6263
data class IMDB(
6364
val rating: Double
@@ -951,6 +952,40 @@ class AggregatesBuilderTest {
951952
assertEquals("Back to the Future", results.first().title)
952953
}
953954

955+
/* NOTE: Test is not run by default. FTS requires the creation of a text index on the collection before running
956+
(see note at top of file for additional setup requirements for FTS).
957+
*/
958+
@Ignore
959+
fun atlasSearchOperatorTest() = runBlocking {
960+
961+
// :snippet-start: atlas-search-pipeline
962+
data class Results(val title: String, val year: Int, val genres: List<String>)
963+
964+
val searchStage = Aggregates.search(
965+
SearchOperator.compound()
966+
.filter(
967+
listOf(
968+
SearchOperator.`in`(SearchPath.fieldPath(Movie::genres.name), listOf("Comedy")),
969+
SearchOperator.phrase(SearchPath.fieldPath(Movie::fullplot.name), "new york"),
970+
SearchOperator.numberRange(SearchPath.fieldPath(Movie::year.name)).gtLt(1950, 2000),
971+
SearchOperator.wildcard(SearchPath.fieldPath(Movie::title.name), "Love *")
972+
)
973+
)
974+
)
975+
976+
val projectStage = Aggregates.project(
977+
Projections.include(Movie::title.name, Movie::year.name, Movie::genres.name))
978+
979+
val pipeline = listOf(searchStage, projectStage)
980+
val resultsFlow = ftsCollection.aggregate<Results>(pipeline)
981+
982+
resultsFlow.collect { println(it) }
983+
// :snippet-end:
984+
985+
val result = resultsFlow.toList()
986+
assertEquals(2, result.size)
987+
}
988+
954989
/* NOTE: Test is not run by default. FTS requires the creation of a text index on the collection before running
955990
(see note at top of file for additional setup requirements for FTS).
956991
*/

examples/src/test/kotlin/AggregationTest.kt

Lines changed: 109 additions & 17 deletions
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", "SunBakeryTrattoria@example.org", listOf(-74.0056649, 40.7452371)), 4, listOf("Pizza", "Pasta", "Italian", "Coffee", "Sandwiches")),
48-
Restaurant("Blue Bagels Grill", Restaurant.Contact("786-555-0102", "BlueBagelsGrill@example.com", listOf(-73.92506, 40.8275556)), 3, listOf("Bagels", "Cookies", "Sandwiches")),
49-
Restaurant("XYZ Bagels Restaurant", Restaurant.Contact("435-555-0190", "XYZBagelsRestaurant@example.net", listOf(-74.0707363, 40.59321569999999)), 4, listOf("Bagels", "Sandwiches", "Coffee")),
50-
Restaurant("Hot Bakery Cafe", Restaurant.Contact("264-555-0171", "HotBakeryCafe@example.net", listOf(-73.96485799999999, 40.761899)), 4, listOf("Bakery", "Cafe", "Coffee", "Dessert")),
51-
Restaurant("Green Feast Pizzeria", Restaurant.Contact("840-555-0102", "GreenFeastPizzeria@example.com", listOf(-74.1220973, 40.6129407)), 2, listOf("Pizza", "Italian")),
52-
Restaurant("ZZZ Pasta Buffet", Restaurant.Contact("769-555-0152", "ZZZPastaBuffet@example.com", listOf(-73.9446421, 40.7253944)), 0, listOf("Pasta", "Italian", "Buffet", "Cafeteria")),
53-
Restaurant("XYZ Coffee Bar", Restaurant.Contact("644-555-0193", "XYZCoffeeBar@example.net", listOf(-74.0166091, 40.6284767)), 5, listOf("Coffee", "Cafe", "Bakery", "Chocolates")),
54-
Restaurant("456 Steak Restaurant", Restaurant.Contact("990-555-0165", "456SteakRestaurant@example.com", listOf(-73.9365108, 40.8497077)), 0, listOf("Steak", "Seafood")),
55-
Restaurant("456 Cookies Shop", Restaurant.Contact("604-555-0149", "456CookiesShop@example.org", listOf(-73.8850023, 40.7494272)), 4, listOf("Bakery", "Cookies", "Cake", "Coffee")),
56-
Restaurant("XYZ Steak Buffet", Restaurant.Contact("229-555-0197", "XYZSteakBuffet@example.org", listOf(-73.9799932, 40.7660886)), 3, listOf("Steak", "Salad", "Chinese"))
51+
Restaurant(
52+
"Sun Bakery Trattoria",
53+
Restaurant.Contact(
54+
"386-555-0189",
55+
"SunBakeryTrattoria@example.org",
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+
"BlueBagelsGrill@example.com",
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+
"XYZBagelsRestaurant@example.net",
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+
"HotBakeryCafe@example.net",
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+
"GreenFeastPizzeria@example.com",
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+
"ZZZPastaBuffet@example.com",
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", "XYZCoffeeBar@example.net", 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+
"456SteakRestaurant@example.com",
122+
listOf(-73.9365108, 40.8497077)
123+
),
124+
0,
125+
listOf("Steak", "Seafood")
126+
),
127+
Restaurant(
128+
"456 Cookies Shop",
129+
Restaurant.Contact(
130< F438 span class="diff-text-marker">+
"604-555-0149",
131+
"456CookiesShop@example.org",
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+
"XYZSteakBuffet@example.org",
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,11 +235,11 @@ 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)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
data class Results(val title: String, val year: Int, val genres: List<String>)
2+
3+
val searchStage = Aggregates.search(
4+
SearchOperator.compound()
5+
.filter(
6+
listOf(
7+
SearchOperator.`in`(SearchPath.fieldPath(Movie::genres.name), listOf("Comedy")),
8+
SearchOperator.phrase(SearchPath.fieldPath(Movie::fullplot.name), "new york"),
9+
SearchOperator.numberRange(SearchPath.fieldPath(Movie::year.name)).gtLt(1950, 2000),
10+
SearchOperator.wildcard(SearchPath.fieldPath(Movie::title.name), "Love *")
11+
)
12+
)
13+
)
14+
15+
val projectStage = Aggregates.project(
16+
Projections.include(Movie::title.name, Movie::year.name, Movie::genres.name))
17+
18+
val pipeline = listOf(searchStage, projectStage)
19+
val resultsFlow = ftsCollection.aggregate<Results>(pipeline)
20+
21+
resultsFlow.collect { println(it) }

source/examples/generated/AggregatesBuilderTest.snippet.movie-data-class.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ data class Movie(
55
val rated: String,
66
val plot: String,
77
val runtime: Int,
8-
val imdb: IMDB
8+
val imdb: IMDB,
9+
val fullplot: String? = "No full plot",
910
){
1011
data class IMDB(
1112
val rating: Double

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

Lines changed: 4 additions & 2 deletions
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

Lines changed: 2 additions & 2 deletions
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,9 @@ first element in the ``categories`` field.
215215
Results(name=456 Cookies Shop, firstCategory=Bakery)
216216
Results(name=XYZ Steak Buffet, firstCategory=Steak)
217217

218+
API Documentation
219+
-----------------
220+
218221
For more information about the methods and classes mentioned in this section,
219222
see the following API Documentation:
220223

source/fundamentals/builders/aggregates.txt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -887,6 +887,31 @@ field in the ``movies`` collection for text that contains the word "Future":
887887
Learn more about the builders from the
888888
`search package API documentation <{+core-api+}/client/model/search/package-summary.html>`__.
889889

890+
.. _kotlin-cr-atlas-search-stage:
891+
892+
Search Operator Methods
893+
~~~~~~~~~~~~~~~~~~~~~~~
894+
895+
.. sharedinclude:: dbx/jvm/atlas-search-operator-helpers.rst
896+
897+
.. replacement:: as-idx-link
898+
899+
the :ref:`kotlin-search-indexes` section of the Indexes guide
900+
901+
.. replacement:: atlas-query-operators-example
902+
903+
.. io-code-block::
904+
905+
.. input:: /examples/generated/AggregatesBuilderTest.snippet.atlas-search-pipeline.kt
906+
:language: kotlin
907+
908+
.. output::
909+
:language: console
910+
:visible: false
911+
912+
Results(title=Love at First Bite, year=1979, genres=[Comedy, Romance])
913+
Results(title=Love Affair, year=1994, genres=[Comedy, Drama])
914+
890915
Atlas Search Metadata
891916
---------------------
892917

source/whats-new.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ and features:
5353
the `SearchOperator <{+core-api+}/client/model/search/SearchOperator.html>`__
5454
interface API documentation
5555

56+
.. replacement:: atlas-query-operators
57+
58+
the :ref:`kotlin-cr-atlas-search-stage` section of the Aggregates
59+
Builders guide
60+
5661
.. _kotlin-coroutine-version-5.3:
5762

5863
What's New in 5.3

0 commit comments

Comments
 (0)
0