Elasticsearch 客户端 for Kotlin:完整指南
Elasticsearch 是一个基于 Lucene 的强大分布式搜索引擎。为了从 Kotlin 应用程序中使用它,官方客户端 Elasticsearch Java Client 被广泛使用,由于 Kotlin 与 JVM 的紧密关系,该客户端完全兼容 Kotlin。在本文中,我们将介绍如何配置客户端、执行基本操作(索引、搜索、删除)以及使用高级功能,例如聚合和过滤。
连接与配置
首先,在 build.gradle.kts(或 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")}然后创建客户端:
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()基本操作
索引文档
创建一个 data class 来表示数据:
data class Product( val id: String, val name: String, val price: Double, val category: String)索引操作如下:
suspend fun indexProduct(product: Product) { client.index { i -> i.index("products") .id(product.id) .document(product) }}
// 调用示例val product = Product("1", "笔记本电脑", 999.99, "电子产品")runBlocking { indexProduct(product) }按字段搜索
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()!! }}删除文档
suspend fun deleteProduct(id: String) { client.delete { d -> d.index("products") .id(id) }}过滤与聚合
Elasticsearch 支持复杂查询。例如,在价格范围内搜索商品并按类别聚合:
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)
// 获取聚合结果 val categories = response.aggregations() ?.get("by_category") ?.sterms() ?.buckets() ?.map { "${it.key()}: ${it.docCount()}" } ?: emptyList()
println("类别: $categories")}批量处理(Bulk API)
对于批量索引,请使用 bulk