Skip to content

Commit c4d8c6e

Browse files
committed
docs update
1 parent c4ef2f0 commit c4d8c6e

File tree

3 files changed

+105
-59
lines changed

3 files changed

+105
-59
lines changed

README.md

+53-30
Original file line numberDiff line numberDiff line change
@@ -114,30 +114,34 @@ And then add dependencies to jvm targets:
114114

115115
### Create a client
116116

117-
First we create a client.
117+
We start by creating a client:
118118

119119
```kotlin
120120
val client = SearchClient()
121121
```
122122

123123
Kotlin has default values for parameters. So, we use sensible defaults for the
124-
`host` and `port` variables to connect to `localhost` and `9200`.
124+
`host` and `port` parameters to connect to `localhost` and `9200`. But of
125+
course you can modify those:
125126

126127
```kotlin
127128
val client = SearchClient(
128129
KtorRestClient(host="localhost", port=9200)
129130
)
130131
```
131132

132-
If you need ro, you can also configure multiple hosts,
133+
If you need to, you can also configure multiple hosts,
133134
add ssl and basic authentication to connect to managed Opensearch or Elasticsearch clusters. If you use
134-
multiple hosts, you can also configure a strategy for selecting the host to connect to. For more on
135-
this, read the [manual](https://jillesvangurp.github.io/kt-search/manual/GettingStarted.html).
135+
multiple hosts, you can also configure a strategy for selecting the host to connect to. And of course
136+
you can completely customize how the client connects.
137+
138+
For more on
139+
this, read the [manual](https://jillesvangurp.github.io/kt-search/manual/GettingStarted.html).
136140

137141
### Documents and data classes
138142

139143
In Kotlin, the preferred way to deal with data would be a data class. This is a simple data class
140-
that we will use below.
144+
that we will use as an example below.
141145

142146
```kotlin
143147
@Serializable
@@ -149,11 +153,21 @@ data class TestDocument(
149153

150154
In the example below we will use this `TestDocument`, which we can serialize using the
151155
[kotlinx.serialization](https://github.com/Kotlin/kotlinx.serialization)
152-
framework. You can also pass in your own serialized json in requests,
153-
so if you want to use e.g. jackson or gson instead,
154-
you can do so easily.
155-
156-
### Creating an index
156+
framework.
157+
158+
**Note**, the client provides a lot of flexibility including to your choice of JSON serialization. The only
159+
part of the code dependent on kotlinx serialization is the client module. But for example the Search DSL
160+
and the other DSLs are not actually dependent on this.
161+
162+
Additionally, if you chooes to use the `IndexRepository`, it comes with a ModelSerialization strategy
163+
that abstracts how to parse/serialize your model classes. A kotlinx serialization implementation is included
164+
but that's easily swapped out for something else. So, if you need to use e.g.
165+
jackson or gson instead, you can do so easily. However, kotlinx serialization is of course the only thing
166+
that works on multi platform.
167+
168+
### Creating an index
169+
170+
Before we can query for `TestDocument` documents, we need to create an index and store some objects:
157171

158172
```kotlin
159173
val indexName = "readme-index"
@@ -172,20 +186,22 @@ client.createIndex(indexName) {
172186
}
173187
```
174188

175-
This creates the index and uses the mappings and settings DSL. With this DSL, you can map fields,
189+
This creates the index and uses the **mappings and settings DSL**. With this DSL, you can map fields,
176190
configure analyzers, etc. This is optional of course; you can just call it without the block
177191
and use the defaults and rely on dynamic mapping.
178192
You can read more about that [here](https://jillesvangurp.github.io/kt-search/manual/IndexManagement.html)
179193

180194
### Adding documents
181195

182-
To fill the index with some content, we need to use bulk operations.
196+
To fill the index with some documents, we need to use bulk indexing operations.
197+
198+
In kt-search this is made very easy with a **Bulk Indexing DSL** that completely abstracts away the book keeping
199+
that you need to do for this in other clients.
183200

184-
In kt-search this is made very easy with a DSL that abstracts away the book keeping
185-
that you need to do for this. The bulk block below creates a `BulkSession`, which does this for you and flushes
201+
The bulk block below creates a `BulkSession`, which does this for you and flushes
186202
operations to Elasticsearch. You can configure and tailor how this works via parameters
187203
that have sensible defaults. For example the number of operations that is flushed is something
188-
that you'd want to probably configure.
204+
that you'd want to probably configure and error handling is something you can customize as well.
189205

190206
The optional `refresh` parameter uses WaitFor as the default. This means that after the block exits, the documents
191207
will have been indexed and are available for searching.
@@ -194,7 +210,7 @@ will have been indexed and are available for searching.
194210
client.bulk(
195211
refresh = Refresh.WaitFor,
196212
// send operations every 2 ops
197-
// default would be 100
213+
// default and more sensible would be 100
198214
bulkSize = 2,
199215
) {
200216
index(
@@ -222,7 +238,7 @@ client.bulk(
222238
```
223239

224240
You can read more about
225-
[bulk operations](https://jillesvangurp.github.io/kt-search/manual/BulkIndexing.html) in the manual.
241+
[bulk operations](https://jillesvangurp.github.io/kt-search/manual/BulkIndexing.html) and how to customize it in the manual.
226242

227243
### Search
228244

@@ -231,10 +247,11 @@ Now that we have some documents in an index, we can do some queries:
231247
```kotlin
232248
// search for some fruit
233249
val results = client.search(indexName) {
250+
// `this` is a SearchDSL instance in the block
234251
query = bool {
235252
must(
236-
// note how we can use property references here
237-
term(TestDocument::tags, "fruit"),
253+
term("tags", "fruit"),
254+
// note how we can also use property references here
238255
matchPhrasePrefix(TestDocument::name, "app")
239256
)
240257
}
@@ -263,7 +280,10 @@ doc apple
263280
{"name":"apple","tags":["fruit"]}
264281
```
265282

266-
You can also construct complex aggregations with the query DSL:
283+
You can also construct complex aggregations with the query DSL.
284+
Aggregation queries are one of the more complex topics in Elasticsearch
285+
and we worked hard to make constructing these programmatically from
286+
Kotlin as easy as possible.
267287

268288
```kotlin
269289
val resp = client.search(indexName) {
@@ -275,7 +295,8 @@ val resp = client.search(indexName) {
275295
minDocCount = 1
276296
})
277297
}
278-
// picking the results apart is just as easy.
298+
// Despite aggregations JSON being very complicated,
299+
// kt-search makes picking the results apart easy.
279300
resp.aggregations
280301
.termsResult("by-tag")
281302
.parsedBuckets.forEach { bucket ->
@@ -295,16 +316,18 @@ These examples show off a few nice features of this library:
295316

296317
- Kotlin DSLs are nice, type safe, and easier to read and write than pure Json. And of course
297318
you get auto completion too. The client includes more DSLs for searching, creating indices and mappings, datastreams,
298-
index life cycle management, bulk operations, aggregations, and more.
319+
index life cycle management, bulk operations, aggregations, and more. All this builds on
320+
[JsonDSL](https://github.com/jillesvangurp/json-dsl), which is a library we created for easily creating
321+
Kotlin DSLs for existing JSON dialects.
299322
- Where in JSON, you use a lot of String literals, kt-search actually allows you to use
300-
property references or enum values as well. So, refactoring your data model doesn't
323+
property references or enum values as well. If you use those, refactoring your data model doesn't
301324
break your mappings and queries.
302325
- Kt-search makes complicated features like bulk operations, aggregations, etc. really easy
303-
to use and accessible. And there is also the IndexRepository, which makes it extremely easy
326+
to use and accessible. And there is also the `IndexRepository`, which makes it extremely easy
304327
to work with and query documents in a given index or data stream.
305-
- While a DSL is nice to have, sometimes it just doesn't have the feature you
306-
need or maybe you want to work with raw json string literal. Kt-search allows you to do both
307-
and mix schema less with type safe kotlin. You can easily add custom
328+
- While a Kotlin DSL is nice to have, sometimes it just doesn't have the feature you
329+
need or maybe you want to work with raw json and use Kotlin's multiline string literals.
330+
Kt-search allows you to do both and mix schema less with type safe kotlin. You can easily add custom
308331
properties to the DSL via a simple `put`. All `JsonDsl` are actually mutable maps.
309332
- Kt-search is designed to be [extensible](https://jillesvangurp.github.io/kt-search/manual/ExtendingTheDSL.html).
310333
It's easy to use the built in features. And you can easily add your own features. This also
@@ -382,8 +405,8 @@ There are several libraries that build on kt-search:
382405

383406
Additionally, I also maintain a few other search related projects that you might find interesting.
384407

385-
- [Rankquest Studio](https://rankquest.jillesvangurp.com) - A user friendly tool that requires no installation process that helps you build and run test cases to measure search relevance for your search products. Rankquest Studio of course uses kt-search but it is also able to talk directly to your API and is designed to work with any kind of search api or product that is able to return lists of results.
386-
- [querylight](https://github.com/jillesvangurp/querylight) - Sometimes Elasticsearch is just overkill. Query light is a tiny in memory search engine that you can embed in your kotlin browser, server, or mobile applications. We use it at FORMATION to support e.g. in app icon search. Querylight comes with its own analyzers and query language.
408+
- [Rankquest Studio](https://rankquest.jillesvangurp.com) - A user friendly tool that requires no installation process that helps you build and run test cases to measure search relevance for your search products. Rankquest Studio of course uses kt-search but it is also able to talk directly to your search API and is designed to work with any kind of search api or product that is able to return lists of results.
409+
- [querylight](https://github.com/jillesvangurp/querylight) - Sometimes Elasticsearch/Opensearch is just overkill. Query light is a tiny but capable in memory search engine that you can embed in your kotlin browser, server, or mobile applications. We use it at FORMATION to support e.g. in app icon search. Querylight comes with its own analyzers and query language.
387410

388411
## Setting up a development environment
389412

docs/src/test/kotlin/documentation/projectreadme/readme.kt

+50-27
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ val projectReadme = sourceGitRepository.md {
4343
+"""
4444
### Create a client
4545
46-
First we create a client.
46+
We start by creating a client:
4747
""".trimIndent()
4848

4949
// this is what we show in the Readme :-)
@@ -53,7 +53,8 @@ val projectReadme = sourceGitRepository.md {
5353

5454
+"""
5555
Kotlin has default values for parameters. So, we use sensible defaults for the
56-
`host` and `port` variables to connect to `localhost` and `9200`.
56+
`host` and `port` parameters to connect to `localhost` and `9200`. But of
57+
course you can modify those:
5758
""".trimIndent()
5859
example {
5960
val client = SearchClient(
@@ -62,17 +63,20 @@ val projectReadme = sourceGitRepository.md {
6263
}
6364

6465
+"""
65-
If you need ro, you can also configure multiple hosts,
66+
If you need to, you can also configure multiple hosts,
6667
add ssl and basic authentication to connect to managed Opensearch or Elasticsearch clusters. If you use
67-
multiple hosts, you can also configure a strategy for selecting the host to connect to. For more on
68-
this, read the [manual](${ManualPages.GettingStarted.publicLink}).
68+
multiple hosts, you can also configure a strategy for selecting the host to connect to. And of course
69+
you can completely customize how the client connects.
70+
71+
For more on
72+
this, read the [manual](${ManualPages.GettingStarted.publicLink}).
6973
""".trimIndent()
7074

7175
+"""
7276
### Documents and data classes
7377
7478
In Kotlin, the preferred way to deal with data would be a data class. This is a simple data class
75-
that we will use below.
79+
that we will use as an example below.
7680
""".trimIndent()
7781

7882
example {
@@ -86,11 +90,21 @@ val projectReadme = sourceGitRepository.md {
8690
+"""
8791
In the example below we will use this `TestDocument`, which we can serialize using the
8892
[kotlinx.serialization](https://github.com/Kotlin/kotlinx.serialization)
89-
framework. You can also pass in your own serialized json in requests,
90-
so if you want to use e.g. jackson or gson instead,
91-
you can do so easily.
93+
framework.
94+
95+
**Note**, the client provides a lot of flexibility including to your choice of JSON serialization. The only
96+
part of the code dependent on kotlinx serialization is the client module. But for example the Search DSL
97+
and the other DSLs are not actually dependent on this.
98+
99+
Additionally, if you chooes to use the `IndexRepository`, it comes with a ModelSerialization strategy
100+
that abstracts how to parse/serialize your model classes. A kotlinx serialization implementation is included
101+
but that's easily swapped out for something else. So, if you need to use e.g.
102+
jackson or gson instead, you can do so easily. However, kotlinx serialization is of course the only thing
103+
that works on multi platform.
92104
93-
### Creating an index
105+
### Creating an index
106+
107+
Before we can query for `TestDocument` documents, we need to create an index and store some objects:
94108
95109
""".trimIndent()
96110
val indexName = "readme-index"
@@ -114,20 +128,22 @@ val projectReadme = sourceGitRepository.md {
114128
}
115129

116130
+"""
117-
This creates the index and uses the mappings and settings DSL. With this DSL, you can map fields,
131+
This creates the index and uses the **mappings and settings DSL**. With this DSL, you can map fields,
118132
configure analyzers, etc. This is optional of course; you can just call it without the block
119133
and use the defaults and rely on dynamic mapping.
120134
You can read more about that [here](${ManualPages.IndexManagement.publicLink})
121135
122136
### Adding documents
123137
124-
To fill the index with some content, we need to use bulk operations.
138+
To fill the index with some documents, we need to use bulk indexing operations.
139+
140+
In kt-search this is made very easy with a **Bulk Indexing DSL** that completely abstracts away the book keeping
141+
that you need to do for this in other clients.
125142
126-
In kt-search this is made very easy with a DSL that abstracts away the book keeping
127-
that you need to do for this. The bulk block below creates a `BulkSession`, which does this for you and flushes
143+
The bulk block below creates a `BulkSession`, which does this for you and flushes
128144
operations to Elasticsearch. You can configure and tailor how this works via parameters
129145
that have sensible defaults. For example the number of operations that is flushed is something
130-
that you'd want to probably configure.
146+
that you'd want to probably configure and error handling is something you can customize as well.
131147
132148
The optional `refresh` parameter uses WaitFor as the default. This means that after the block exits, the documents
133149
will have been indexed and are available for searching.
@@ -136,7 +152,7 @@ val projectReadme = sourceGitRepository.md {
136152
client.bulk(
137153
refresh = Refresh.WaitFor,
138154
// send operations every 2 ops
139-
// default would be 100
155+
// default and more sensible would be 100
140156
bulkSize = 2,
141157
) {
142158
index(
@@ -164,7 +180,7 @@ val projectReadme = sourceGitRepository.md {
164180
}
165181
+"""
166182
You can read more about
167-
[bulk operations](${ManualPages.BulkIndexing.publicLink}) in the manual.
183+
[bulk operations](${ManualPages.BulkIndexing.publicLink}) and how to customize it in the manual.
168184
169185
### Search
170186
@@ -173,10 +189,11 @@ val projectReadme = sourceGitRepository.md {
173189
example {
174190
// search for some fruit
175191
val results = client.search(indexName) {
192+
// `this` is a SearchDSL instance in the block
176193
query = bool {
177194
must(
178-
// note how we can use property references here
179-
term(TestDocument::tags, "fruit"),
195+
term("tags", "fruit"),
196+
// note how we can also use property references here
180197
matchPhrasePrefix(TestDocument::name, "app")
181198
)
182199
}
@@ -198,7 +215,10 @@ val projectReadme = sourceGitRepository.md {
198215
}.printStdOut()
199216

200217
+"""
201-
You can also construct complex aggregations with the query DSL:
218+
You can also construct complex aggregations with the query DSL.
219+
Aggregation queries are one of the more complex topics in Elasticsearch
220+
and we worked hard to make constructing these programmatically from
221+
Kotlin as easy as possible.
202222
""".trimIndent()
203223
example {
204224
val resp = client.search(indexName) {
@@ -210,7 +230,8 @@ val projectReadme = sourceGitRepository.md {
210230
minDocCount = 1
211231
})
212232
}
213-
// picking the results apart is just as easy.
233+
// Despite aggregations JSON being very complicated,
234+
// kt-search makes picking the results apart easy.
214235
resp.aggregations
215236
.termsResult("by-tag")
216237
.parsedBuckets.forEach { bucket ->
@@ -224,16 +245,18 @@ val projectReadme = sourceGitRepository.md {
224245
225246
- Kotlin DSLs are nice, type safe, and easier to read and write than pure Json. And of course
226247
you get auto completion too. The client includes more DSLs for searching, creating indices and mappings, datastreams,
227-
index life cycle management, bulk operations, aggregations, and more.
248+
index life cycle management, bulk operations, aggregations, and more. All this builds on
249+
[JsonDSL](https://github.com/jillesvangurp/json-dsl), which is a library we created for easily creating
250+
Kotlin DSLs for existing JSON dialects.
228251
- Where in JSON, you use a lot of String literals, kt-search actually allows you to use
229-
property references or enum values as well. So, refactoring your data model doesn't
252+
property references or enum values as well. If you use those, refactoring your data model doesn't
230253
break your mappings and queries.
231254
- Kt-search makes complicated features like bulk operations, aggregations, etc. really easy
232-
to use and accessible. And there is also the IndexRepository, which makes it extremely easy
255+
to use and accessible. And there is also the `IndexRepository`, which makes it extremely easy
233256
to work with and query documents in a given index or data stream.
234-
- While a DSL is nice to have, sometimes it just doesn't have the feature you
235-
need or maybe you want to work with raw json string literal. Kt-search allows you to do both
236-
and mix schema less with type safe kotlin. You can easily add custom
257+
- While a Kotlin DSL is nice to have, sometimes it just doesn't have the feature you
258+
need or maybe you want to work with raw json and use Kotlin's multiline string literals.
259+
Kt-search allows you to do both and mix schema less with type safe kotlin. You can easily add custom
237260
properties to the DSL via a simple `put`. All `JsonDsl` are actually mutable maps.
238261
- Kt-search is designed to be [extensible](${ManualPages.ExtendingTheDSL.publicLink}).
239262
It's easy to use the built in features. And you can easily add your own features. This also

0 commit comments

Comments
 (0)