Elasticsearch client for Kotlin: integration, examples, and capabilities

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Elasticsearch client for Kotlin: complete guide



Elasticsearch is a powerful distributed search engine based on Lucene. To work with it from Kotlin applications, the official Elasticsearch Java Client is used, which is fully compatible with Kotlin due to its proximity to the JVM. In this article, we will cover how to configure the client, perform basic operations (indexing, search, deletion), and use advanced features such as aggregations and filtering.



Connection and setup



First, add the dependency in build.gradle.kts (or build.gradle):



// build.gradle.ktsdependencies {    implementation("co.elastic.clients:elasticsearch-java:8.15.0")    implementation("com.fasterxml.jackson.core:jackson-databind:2.17.0")    implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.17.0")}


Then create the client:



import co.elastic.clients.elasticsearch.ElasticsearchClientimport co.elastic.clients.json.jackson.JacksonJsonpMapperimport co.elastic.clients.transport.rest_client.RestClientTransportimport org.apache.http.HttpHostimport org.elasticsearch.client.RestClient

fun createClient(): ElasticsearchClient { val restClient = RestClient.builder( HttpHost("localhost", 9200, "http") ).build()

val transport = RestClientTransport(restClient, JacksonJsonpMapper()) return ElasticsearchClient(transport)}

val client = createClient()


Basic operations



Indexing a document



Create a data class to represent the data:



data class Product(    val id: String,    val name: String,    val price: Double,    val category: String)


Indexing is done as follows:



suspend fun indexProduct(product: Product) {    client.index { i ->        i.index("products")            .id(product.id)            .document(product)    }}

// Example callval product = Product("1", "Laptop", 999.99, "Electronics")runBlocking { indexProduct(product) }


Search by fields



suspend fun searchByName(name: String): List<Product> {    val response = client.search<Product>({ s ->        s.index("products")            .query { q ->                q.match { m ->                    m.field("name")                        .query(name)                }            }    }, Product::class.java)

return response.hits().hits().map { it.source()!! }}


Deleting a document



suspend fun deleteProduct(id: String) {    client.delete { d ->        d.index("products")            .id(id)    }}


Filtering and aggregations



Elasticsearch supports complex queries. For example, searching for products in a price range with aggregation by category:



suspend fun searchWithAggregation(minPrice: Double, maxPrice: Double) {    val response = client.search<Product>({ s ->        s.index("products")            .query { q ->                q.range { r ->                    r.field("price")                        .gte(minPrice.toString())                        .lte(maxPrice.toString())                }            }            .aggregations("by_category") { a ->                a.terms { t ->                    t.field("category")                }            }    }, Product::class.java)

// Get aggregation results val categories = response.aggregations() ?.get("by_category") ?.sterms() ?.buckets() ?.map { "${it.key()}: ${it.docCount()}" } ?: emptyList()

println("Categories: $categories")}


Batch processing (Bulk API)



For mass indexing, use bulk

Recommendations