Elasticsearch-Client für Rust: elasticsearch-rs
\n\nElasticsearch ist ein leistungsstarkes verteiltes Such- und Analysesystem, das auf Apache Lucene basiert. Für die Interaktion mit Elasticsearch aus Rust-Anwendungen heraus gibt es den offiziellen Client – elasticsearch-rs. Diese Bibliothek bietet einen vollständigen Satz von Werkzeugen für die Arbeit mit der REST-API von Elasticsearch, einschließlich Indizierung, Suche, Aggregationen und Cluster-Verwaltung. In diesem Artikel werden wir die Installation, Konfiguration und die wichtigsten Funktionen von elasticsearch-rs mit Codebeispielen im Detail behandeln.
\n\nWas ist elasticsearch-rs?
\nelasticsearch-rs ist der offizielle asynchrone Elasticsearch-Client für die Programmiersprache Rust, entwickelt von der Firma Elastic. Er basiert auf der beliebten asynchronen HTTP-Client-Bibliothek reqwest und bietet eine typsichere API für alle Elasticsearch-Endpunkte. Die Hauptvorteile sind:
- \n
- Vollständige Unterstützung für Elasticsearch 7.x und 8.x – alle grundlegenden Operationen: CRUD, Suche, Aggregationen, Indexverwaltung. \n
- Asynchronität – verwendet async/await, was eine effiziente Verarbeitung vieler Anfragen ermöglicht. \n
- Typsicherheit – Anfrage- und Antwortstrukturen sind streng typisiert, was die Anzahl der Laufzeitfehler reduziert. \n
- Automatische Serialisierung/Deserialisierung – über
serdeundserde_json. \n - Unterstützung für Authentifizierung – Basic Auth, API-Schlüssel, SSL/TLS. \n
Installation
\nFügen Sie die Abhängigkeit in Cargo.toml hinzu:
[dependencies]\nelasticsearch = "8.14.0"\nserde = { version = "1.0", features = ["derive"] }\nserde_json = "1.0"\ntokio = { version = "1", features = ["full"] }\n\nGrundlegende Verbindung
\nErstellen wir einen Client, der eine Verbindung zu einer lokalen Elasticsearch-Instanz herstellt:
\nuse elasticsearch::Elasticsearch;\nuse elasticsearch::http::transport::Transport;\nuse serde_json::json;\n\n#[tokio::main]\nasync fn main() -> Result<(), Box<dyn std::error::Error>> {\n let transport = Transport::single_node("http://localhost:9200")?;\n let client = Elasticsearch::new(transport);\n // Verbindung prüfen\n let response = client.ping().send().await?;\n println!("Elasticsearch verfügbar: {}", response.status_code());\n Ok(())\n}\n\nGrundlegende Operationen: CRUD
\n\n1. Dokument indizieren
\nFügen wir ein Dokument mit Informationen zu einem Buch im Index books hinzu:
#[derive(Serialize, Deserialize, Debug)]\nstruct Book {\n title: String,\n author: String,\n year: u16,\n isbn: String,\n}\n\nlet book = Book {\n title: "Rust in Aktion".into(),\n author: "Tim McNamara".into(),\n year: 2023,\n isbn: "978-5-4461-2345-6".into(),\n};\n\nlet response = client\n .index(IndexParts::IndexId("books", "1"))\n .body(json!(book))\n .send()\n .await?;\n\nprintln!("Dokument indiziert: {:?}", response.body());\n\n2. Dokument abrufen
\nlet response = client\n .get(GetParts::IndexId("books", "1"))\n .send()\n .await?;\n\nif response.status_code().is_success() {\n let book: Book = response.json().await?;\n println!("Dokument gefunden: {:?}", book);\n}\n\n3. Dokument aktualisieren
\nlet response = client\n .update(UpdateParts::IndexId("books", "1"))\n .body(json!({\n "doc": { "year": 2024 }\n }))\n .send()\n .await?;\n\nprintln!("Aktualisiert: {:?}", response.body());\n\n4. Dokument löschen
\nlet response = client\n .delete(DeleteParts::IndexId("books", "1"))\n .send()\n .await?;\n\nprintln!("Gelöscht: {:?}", response.body());\n\nSuche mit Query DSL
\nFühren wir eine Volltextsuche im Feld title durch:
use elasticsearch::SearchParts;\n\nl