Skip to content

Commit 29198f6

Browse files
authored
(DOCSP-29214): CRUD > Search Text page (#12)
* (DOCSP-29214): Search Text page * Fix autobuilder errors * Optimize imports * Convert to Flow.collect { } * Convert to io-code blocks
1 parent 19b0326 commit 29198f6

10 files changed

+200
-51
lines changed
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
import com.mongodb.client.model.Filters
2+
import com.mongodb.client.model.Indexes
3+
import com.mongodb.client.model.Sorts.ascending
4+
import com.mongodb.client.model.TextSearchOptions
5+
import com.mongodb.kotlin.client.coroutine.MongoClient
6+
import io.github.cdimascio.dotenv.dotenv
7+
import kotlinx.coroutines.flow.toList
8+
import kotlinx.coroutines.runBlocking
9+
import org.bson.codecs.pojo.annotations.BsonId
10+
import org.junit.jupiter.api.AfterAll
11+
import org.junit.jupiter.api.Assertions.*
12+
import org.junit.jupiter.api.BeforeAll
13+
import org.junit.jupiter.api.TestInstance
14+
import kotlin.test.*
15+
16+
// :snippet-start: search-data-model
17+
data class Movies(
18+
@BsonId val id: Int,
19+
val title: String,
20+
val tags: List<String>
21+
)
22+
// :snippet-end:
23+
24+
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
25+
internal class SearchTextTest {
26+
27+
companion object {
28+
val dotenv = dotenv()
29+
val client = MongoClient.create(dotenv["MONGODB_CONNECTION_URI"])
30+
val database = client.getDatabase("movies")
31+
val collection = database.getCollection<Movies>("fast_and_furious_movies")
32+
33+
@BeforeAll
34+
@JvmStatic
35+
private fun beforeAll() {
36+
runBlocking {
37+
val fastAndFuriousMovies = listOf(
38+
Movies(1, "2 Fast 2 Furious", listOf("undercover", "drug dealer")),
39+
Movies(2, "Fast 5", listOf("bank robbery", "full team")),
40+
Movies(3, "Furious 7", listOf("emotional")),
41+
Movies(4, "The Fate of the Furious", listOf("betrayal"))
42+
)
43+
collection.insertMany(fastAndFuriousMovies)
44+
}
45+
}
46+
47+
@AfterAll
48+
@JvmStatic
49+
private fun afterAll() {
50+
runBlocking {
51+
collection.drop()
52+
client.close()
53+
}
54+
}
55+
}
56+
57+
58+
@Test
59+
fun createIndexTest() = runBlocking {
60+
// :snippet-start: text-index
61+
collection.createIndex(Indexes.text("title"))
62+
// :snippet-end:
63+
// Junit test for the above code
64+
val testFilter = Filters.text("Furious")
65+
collection.find(testFilter).collect { println(it) }
66+
val expected = listOf(
67+
Movies(1, "2 Fast 2 Furious", listOf("undercover", "drug dealer")),
68+
Movies(3, "Furious 7", listOf("emotional")),
69+
Movies(4, "The Fate of the Furious", listOf("betrayal"))
70+
)
71+
assertEquals(expected, collection.find(testFilter).sort(ascending("_id")).toList() )
72+
}
73+
74+
@Test
75+
fun specifyOptionsTest() = runBlocking {
76+
collection.createIndex(Indexes.text("title"))
77+
// :snippet-start: specify-options
78+
val options: TextSearchOptions = TextSearchOptions().caseSensitive(true)
79+
val filter = Filters.text("SomeText", options)
80+
// :snippet-end:
81+
// Junit test for the above code
82+
assertTrue(collection.find(filter).toList().isEmpty() )
83+
}
84+
85+
@Test
86+
fun searchTermTest() = runBlocking {
87+
collection.createIndex(Indexes.text("title"))
88+
// :snippet-start: search-term
89+
val filter = Filters.text("fast")
90+
collection.find(filter).collect { println(it) }
91+
// :snippet-end:
92+
// Junit test for the above code
93+
val expected = listOf(
94+
Movies(1, "2 Fast 2 Furious", listOf("undercover", "drug dealer")),
95+
Movies(2, "Fast 5", listOf("bank robbery", "full team"))
96+
)
97+
assertEquals(expected, collection.find(filter).sort(ascending("_id")).toList() )
98+
}
99+
100+
@Test
101+
fun searchMultipleTermsTest() = runBlocking {
102+
collection.createIndex(Indexes.text("title"))
103+
// :snippet-start: search-multiple-terms
104+
val filter = Filters.text("fate 7")
105+
collection.find(filter).collect { println(it) }
106+
// :snippet-end:
107+
// Junit test for the above code
108+
val expected = listOf(
109+
Movies(3, "Furious 7", listOf("emotional")),
110+
Movies(4, "The Fate of the Furious", listOf("betrayal"))
111+
)
112+
assertEquals(expected, collection.find(filter).toList() )
113+
}
114+
115+
@Test
116+
fun searchPhraseTest() = runBlocking {
117+
collection.createIndex(Indexes.text("title"))
118+
// :snippet-start: search-phrase
119+
val filter = Filters.text("\"fate of the furious\"")
120+
collection.find(filter).collect { println(it) }
121+
// :snippet-end:
122+
// Junit test for the above code
123+
val expected = listOf(
124+
Movies(4, "The Fate of the Furious", listOf("betrayal"))
125+
)
126+
assertEquals(expected, collection.find(filter).toList() )
127+
}
128+
129+
@Test
130+
fun excludeTermTest() = runBlocking {
131+
collection.createIndex(Indexes.text("title"))
132+
// :snippet-start: exclude-term
133+
val filter = Filters.text("furious -fast")
134+
collection.find(filter).collect { println(it) }
135+
// :snippet-end:
136+
// Junit test for the above code
137+
val expected = listOf(
138+
Movies(3, "Furious 7", listOf("emotional")),
139+
Movies(4, "The Fate of the Furious", listOf("betrayal"))
140+
)
141+
assertEquals(expected, collection.find(filter).sort(ascending("_id")).toList() )
142+
}
143+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
val filter = Filters.text("furious -fast")
2+
collection.find(filter).collect { println(it) }
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
data class Movies(
2+
@BsonId val id: Int,
3+
val title: String,
4+
val tags: List<String>
5+
)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
val filter = Filters.text("fate 7")
2+
collection.find(filter).collect { println(it) }
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
val filter = Filters.text("\"fate of the furious\"")
2+
collection.find(filter).collect { println(it) }
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
val filter = Filters.text("fast")
2+
collection.find(filter).collect { println(it) }
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
val filter = Filters.and(Filters.gt("_id", 1))
2+
collection.find(filter).toList().forEach { println(it) }
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
val options: TextSearchOptions = TextSearchOptions().caseSensitive(true)
2+
val filter = Filters.text("SomeText", options)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
collection.createIndex(Indexes.text("title"))

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

Lines changed: 39 additions & 51 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 run a **text search** in the MongoDB
19-
Java driver.
19+
Kotlin driver.
2020

2121
You can use a text search to retrieve documents that contain a **term**
2222
or a **phrase** in a specified field. A term is a sequence of characters
@@ -52,6 +52,11 @@ movie franchise. Each document contains a title field and a tags field.
5252
{ "_id": 3, "title": "Furious 7", "tags": ["emotional"] }
5353
{ "_id": 4, "title": "The Fate of the Furious", "tags": ["betrayal"] }
5454

55+
This data is modeled with the following Kotlin data class:
56+
57+
.. literalinclude:: /examples/generated/SearchTextTest.snippet.search-data-model.kt
58+
:language: kotlin
59+
5560
Text Index
5661
~~~~~~~~~~
5762

@@ -65,11 +70,8 @@ searches on the ``title`` field, create a text index using the
6570
:ref:`Indexes <index-text-indexes>` builder with the following
6671
snippet:
6772

68-
.. literalinclude:: /includes/fundamentals/code-snippets/SearchText.java
69-
:language: java
70-
:dedent:
71-
:start-after: begin textIndex
72-
:end-before: end textIndex
73+
.. literalinclude:: /examples/generated/SearchTextTest.snippet.text-index.kt
74+
:language: kotlin
7375

7476
For more information, see the following resources:
7577

@@ -105,16 +107,14 @@ which means the search matches lowercase and uppercase values.
105107

106108
To specify a case sensitive search, use the following snippet:
107109

108-
.. code-block:: java
109-
110-
TextSearchOptions options = new TextSearchOptions().caseSensitive(true);
111-
Bson filter = Filters.text("SomeText", options);
110+
.. literalinclude:: /examples/generated/SearchTextTest.snippet.specify-options.kt
111+
:language: kotlin
112112

113113
For more information about the methods and classes mentioned in this section,
114114
see the following API Documentation:
115115

116-
- `Filters.text() <{+api+}/apidocs/mongodb-driver-core/com/mongodb/client/model/Filters.html#text(java.lang.String)>`__
117-
- `TextSearchOptions <{+api+}/apidocs/mongodb-driver-core/com/mongodb/client/model/TextSearchOptions.html>`__
116+
- `Filters.text() <TODO:(DOCSP-29169)>`__
117+
- `TextSearchOptions <TODO:(DOCSP-29169)>`__
118118

119119
.. _term_search:
120120

@@ -131,19 +131,16 @@ The following example runs a text search on the documents in the
131131
``fast_and_furious_movies`` collection for titles that contain the
132132
term "fast":
133133

134-
.. literalinclude:: /includes/fundamentals/code-snippets/SearchText.java
135-
:language: java
136-
:dedent:
137-
:start-after: begin termExample
138-
:end-before: end termExample
134+
.. io-code-block::
139135

140-
The following shows the output of the preceding code:
136+
.. input:: /examples/generated/SearchTextTest.snippet.search-term.kt
137+
:language: kotlin
141138

142-
.. code-block:: json
143-
:copyable: false
139+
.. output::
140+
:language: console
144141

145-
{ "_id": 1, "title": "2 Fast 2 Furious ", "tags": ["undercover", "drug dealer"] }
146-
{ "_id": 2, "title": "Fast 5", "tags": ["bank robbery", "full team"] }
142+
Movies(id=1, title=2 Fast 2 Furious, tags=[undercover, drug dealer])
143+
Movies(id=2, title=Fast 5, tags=[bank robbery, full team])
147144

148145
To match multiple terms in your text search, separate each term
149146
with spaces in the ``Filters.text()`` builder method. The builder method
@@ -158,19 +155,16 @@ The following example runs a text search on the documents in the
158155
``fast_and_furious_movies`` collection for titles that contain the
159156
terms "fate" or "7":
160157

161-
.. literalinclude:: /includes/fundamentals/code-snippets/SearchText.java
162-
:language: java
163-
:dedent:
164-
:start-after: begin multipleTermExample
165-
:end-before: end multipleTermExample
158+
.. io-code-block::
166159

167-
The following shows the output of the preceding code:
160+
.. input:: /examples/generated/SearchTextTest.snippet.search-multiple-terms.kt
161+
:language: kotlin
168162

169-
.. code-block:: json
170-
:copyable: false
163+
.. output::
164+
:language: console
171165

172-
{ "_id": 3, "title": "Furious 7", "tags": ["emotional"] }
173-
{ "_id": 4, "title": "The Fate of the Furious", "tags": ["betrayal"] }
166+
Movies(id=3, title=Furious 7, tags=[emotional])
167+
Movies(id=4, title=The Fate of the Furious, tags=[betrayal])
174168

175169
Search Text by a Phrase
176170
~~~~~~~~~~~~~~~~~~~~~~~
@@ -188,18 +182,15 @@ The following example runs a text search on the documents in the
188182
``fast_and_furious_movies`` collection for titles that contain the
189183
phrase "fate of the furious":
190184

191-
.. literalinclude:: /includes/fundamentals/code-snippets/SearchText.java
192-
:language: java
193-
:dedent:
194-
:start-after: begin phraseExample
195-
:end-before: end phraseExample
185+
.. io-code-block::
196186

197-
The following shows the output of the preceding code:
187+
.. input:: /examples/generated/SearchTextTest.snippet.search-phrase.kt
188+
:language: kotlin
198189

199-
.. code-block:: json
200-
:copyable: false
190+
.. output::
191+
:language: console
201192

202-
{ "_id": 4, "title": "The Fate of the Furious", "tags": ["betrayal"] }
193+
Movies(id=4, title=The Fate of the Furious, tags=[betrayal])
203194

204195
Search Text with Terms Excluded
205196
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -223,16 +214,13 @@ The following example runs a text search on the documents in the
223214
``fast_and_furious_movies`` collection for titles that contain the
224215
term "furious", but do not contain the term "fast":
225216

226-
.. literalinclude:: /includes/fundamentals/code-snippets/SearchText.java
227-
:language: java
228-
:dedent:
229-
:start-after: begin negateExample
230-
:end-before: end negateExample
217+
.. io-code-block::
231218

232-
The following shows the output of the preceding code:
219+
.. input:: /examples/generated/SearchTextTest.snippet.exclude-term.kt
220+
:language: kotlin
233221

234-
.. code-block:: json
235-
:copyable: false
222+
.. output::
223+
:language: console
236224

237-
{ "_id": 3, "title": "Furious 7", "tags": ["emotional"] }
238-
{ "_id": 4, "title": "The Fate of the Furious", "tags": ["betrayal"] }
225+
Movies(id=3, title=Furious 7, tags=[emotional])
226+
Movies(id=4, title=The Fate of the Furious, tags=[betrayal])

0 commit comments

Comments
 (0)