Elasticsearch клиент для Kotlin: мощный инструмент для поиска и аналитики
Elasticsearch — это распределённая поисковая и аналитическая система на базе Apache Lucene, которая позволяет быстро выполнять полнотекстовый поиск, агрегации и анализ больших объёмов данных. Для работы с Elasticsearch из Kotlin-приложений существует несколько клиентов, но наиболее современным и рекомендуемым является Elasticsearch Java Client (начиная с версии 7.16) с полной поддержкой Kotlin. В этой статье мы рассмотрим его установку, настройку и основные операции.
Установка и подключение
Для начала добавьте зависимость в ваш 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")
}
Для 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>
Создание клиента
Библиотека использует паттерн Builder для конфигурации. Ниже приведён пример создания клиента с подключением к локальному экземпляру Elasticsearch:
import co.elastic.clients.elasticsearch.ElasticsearchClient
import co.elastic.clients.json.jackson.JacksonJsonpMapper
import co.elastic.clients.transport.ElasticsearchTransport
import co.elastic.clients.transport.rest_client.RestClientTransport
import org.apache.http.HttpHost
import org.elasticsearch.client.RestClient
fun createElasticsearchClient(): ElasticsearchClient {
// Создаём HTTP-клиент (без аутентификации)
val restClient = RestClient.builder(
HttpHost("localhost", 9200, "http")
).build()
// Создаём транспорт с JSON-маппером Jackson
val transport: ElasticsearchTransport = RestClientTransport(
restClient,
JacksonJsonpMapper()
)
// И возвращаем готовый клиент
return ElasticsearchClient(transport)
}
Для продакшн-среды рекомендуется использовать аутентификацию и 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()
Работа с индексами
Перед выполнением операций с документами нужно создать индекс (если он отсутствует). Пример создания индекса с маппингом:
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("Индекс создан: ${response.acknowledged}")
}
CRUD операции с документами
Создание/обновление документа (Index API)
data class Article(
val title: String,
val content: String,
val timestamp: String = java.time.Instant.now().toString()
)
suspend fun indexDocument(client: ElasticsearchClient, indexName: String, id: String, article: Article) {
val response = client.index { index ->
index
.index(indexName)
.id(id)
.document(article)
}
println("Документ проиндексирован: результат=${response.result()}")
}
Получение документа по ID
suspend fun getDocument(client: ElasticsearchClient, indexName: String, id: String): Article? {
val response = client.get { get ->
get
.index(indexName)
.id(id)
}
return if (response.found()) {
response.source() as? Article
} else {
println("Документ не найден")
null
}
}
Удаление документа
suspend fun deleteDocument(client: ElasticsearchClient, indexName: String, id: String) {
val response = client.delete { delete ->
delete
.index(indexName)
.id(id)
}
println("Документ удалён: результат=${response.result()}")
}
Поиск и запросы
Одна из ключевых возможностей — полнотекстовый поиск. Пример простого поиска по полю content