Elasticsearch-Client für Kotlin: Vollständige Anleitung
\n\nElasticsearch ist ein leistungsstarkes, verteiltes Suchsystem, das auf Lucene basiert. Für die Arbeit damit aus Kotlin-Anwendungen wird der offizielle Client Elasticsearch Java Client verwendet, der dank seiner Nähe zur JVM vollständig mit Kotlin kompatibel ist. In diesem Artikel werden wir behandeln, wie man den Client einrichtet, grundlegende Operationen (Indizierung, Suche, Löschen) durchführt und erweiterte Funktionen wie Aggregationen und Filterung nutzt.
\n\nVerbindung und Konfiguration
\n\nFügen Sie zunächst die Abhängigkeit in build.gradle.kts (oder build.gradle) hinzu:
// build.gradle.kts\ndependencies {\n implementation("co.elastic.clients:elasticsearch-java:8.15.0")\n implementation("com.fasterxml.jackson.core:jackson-databind:2.17.0")\n implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.17.0")\n}\n\nErstellen Sie dann den Client:
\n\nimport co.elastic.clients.elasticsearch.ElasticsearchClient\nimport co.elastic.clients.json.jackson.JacksonJsonpMapper\nimport co.elastic.clients.transport.rest_client.RestClientTransport\nimport org.apache.http.HttpHost\nimport org.elasticsearch.client.RestClient\n\nfun createClient(): ElasticsearchClient {\n val restClient = RestClient.builder(\n HttpHost("localhost", 9200, "http")\n ).build()\n\n val transport = RestClientTransport(restClient, JacksonJsonpMapper())\n return ElasticsearchClient(transport)\n}\n\nval client = createClient()\n\nGrundlegende Operationen
\n\nIndizierung eines Dokuments
\n\nErstellen Sie eine data class zur Darstellung der Daten:
\n\ndata class Product(\n val id: String,\n val name: String,\n val price: Double,\n val category: String\n)\n\nDie Indizierung erfolgt wie folgt:
\n\nsuspend fun indexProduct(product: Product) {\n client.index { i ->\n i.index("products")\n .id(product.id)\n .document(product)\n }\n}\n\n// Beispielaufruf\nval product = Product("1", "Laptop", 999.99, "Elektronik")\nrunBlocking { indexProduct(product) }\n\nSuche nach Feldern
\n\nsuspend fun searchByName(name: String): List<Product> {\n val response = client.search<Product>({ s ->\n s.index("products")\n .query { q ->\n q.match { m ->\n m.field("name")\n .query(name)\n }\n }\n }, Product::class.java)\n\n return response.hits().hits().map { it.source()!! }\n}\n\nLöschen eines Dokuments
\n\nsuspend fun deleteProduct(id: String) {\n client.delete { d ->\n d.index("products")\n .id(id)\n }\n}\n\nFilterung und Aggregationen
\n\nElasticsearch unterstützt komplexe Abfragen. Zum Beispiel die Suche nach Produkten in einem Preisbereich mit Aggregation nach Kategorien:
\n\nsuspend fun searchWithAggregation(minPrice: Double, maxPrice: Double) {\n val response = client.search<Product>({ s ->\n s.index("products")\n .query { q ->\n q.range { r ->\n r.field("price")\n .gte(minPrice.toString())\n .lte(maxPrice.toString())\n }\n }\n .aggregations("by_category") { a ->\n a.terms { t ->\n t.field("category")\n }\n }\n }, Product::class.java)\n\n // Aggregationsergebnisse abrufen\n val categories = response.aggregations()\n ?.get("by_category")\n ?.sterms()\n ?.buckets()\n ?.map { "${it.key()}: ${it.docCount()}" }\n ?: emptyList()\n\n println("Kategorien: $categories")\n}\n\nStapelverarbeitung (Bulk API)
\n\nFür die Massenindizierung verwenden Sie bulk