Elasticsearch Client for Kotlin: A Powerful Tool for Search and Analytics
Elasticsearch is a distributed search and analytics system based on Apache Lucene that enables fast full-text search, aggregations, and analysis of large volumes of data. For working with Elasticsearch from Kotlin applications, there are several clients, but the most modern and recommended one is the Elasticsearch Java Client (starting from version 7.16) with full Kotlin support. In this article, we will cover its installation, configuration, and basic operations.
Installation and Setup
First, add the dependency to your build.gradle.kts:
dependencies { implementation("co.elastic.clients:elasticsearch-java:8.15.0") implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.17.0") implementation("jakarta.json:jakarta.json-api:2.1.3")}For Maven (pom.xml):
<dependency> <groupId>co.elastic.clients</groupId> <artifactId>elasticsearch-java</artifactId> <version>8.15.0</version></dependency><dependency> <groupId>com.fasterxml.jackson.module</groupId> <artifactId>jackson-module-kotlin</artifactId> <version>2.17.0</version></dependency>Creating a Client
The library uses the Builder pattern for configuration. Below is an example of creating a client connected to a local Elasticsearch instance:
import co.elastic.clients.elasticsearch.ElasticsearchClientimport co.elastic.clients.json.jackson.JacksonJsonpMapperimport co.elastic.clients.transport.ElasticsearchTransportimport co.elastic.clients.transport.rest_client.RestClientTransportimport org.apache.http.HttpHostimport org.elasticsearch.client.RestClient
fun createElasticsearchClient(): ElasticsearchClient { // Create an HTTP client (without authentication) val restClient = RestClient.builder( HttpHost("localhost", 9200, "http") ).build()
// Create a transport with the Jackson JSON mapper val transport: ElasticsearchTransport = RestClientTransport( restClient, JacksonJsonpMapper() )
// And return the ready client return ElasticsearchClient(transport)}For production environments, it is recommended to use authentication and HTTPS:
val credentialsProvider = BasicCredentialsProvider()credentialsProvider.setCredentials( AuthScope.ANY, UsernamePasswordCredentials("elastic", "your_password"))
val restClient = RestClient.builder( HttpHost("your-cluster.com", 9243, "https")).setHttpClientConfigCallback { httpClientBuilder -> httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider)}.build()Working with Indices
Before performing operations on documents, you need to create an index (if it does not exist). Example of creating an index with a mapping:
suspend fun createIndex(client: ElasticsearchClient, indexName: String) { val response = client.indices().create { createBuilder -> createBuilder .index(indexName) .mappings { mappings -> mappings .properties("title") { prop -> prop.text { it } } .properties("content") { prop -> prop.text { it } } .properties("timestamp") { prop -> prop.date { it } } } } println("Index created: ${response.acknowledged}")}CRUD Operations with Documents
Creating/Updating a Document (Index API)
data class Article( val title: String, val content: String, val timestamp: String = java.time.Instant.now().toString())
suspend fun indexDocument(client: E