Indizieren und Aktualisieren von Dokumenten mit der Elasticsearch REST API
Meistern Sie die grundlegenden CRUD-Operationen (Create, Read, Update, Delete) in Elasticsearch mithilfe der REST API. Diese Anleitung beschreibt detailliert die erforderlichen HTTP-Anfragen, Endpunkte und JSON-Nutzlasten zum Indizieren neuer Dokumente (mit oder ohne angegebene IDs) und zum Durchführen granularer, partieller Aktualisierungen vorhandener Datensätze. Lernen Sie praktische `curl`-Beispiele für atomare Aktualisierungen, scriptbasierte Änderungen und effiziente Bulk-Datenerfassung.
Indizieren und Aktualisieren von Dokumenten mit der Elasticsearch REST API
Das Indizieren und Aktualisieren von Dokumenten mit der Elasticsearch REST API sieht zunächst einfach aus: Senden Sie JSON an einen Endpunkt und erhalten Sie JSON zurück. Die Teile, die in der Produktion wichtig sind, sind jedoch spezifischer. Erstellen Sie ein neues Dokument oder ersetzen Sie ein altes? Soll Elasticsearch die ID generieren oder benötigen Sie eine ID aus Ihrem Quellsystem? Führen Sie eine partielle Aktualisierung durch oder überschreiben Sie versehentlich Felder, die Sie behalten wollten?
Die folgenden Beispiele verwenden localhost:9200, einen Index namens products und einfaches curl. In einem echten Cluster benötigen Sie möglicherweise auch HTTPS, Authentifizierung und eine Zertifikatsoption.
curl -u elastic:password --cacert http_ca.crt https://es.example.com:9200/
Erstellen eines Dokuments mit automatischer ID
Verwenden Sie POST /{index}/_doc, wenn Elasticsearch die Dokument-ID zuweisen kann.
curl -X POST "localhost:9200/products/_doc" \
-H "Content-Type: application/json" \
-d '{
"sku": "mouse-x1",
"name": "Wireless Mouse X1",
"price": 25.99,
"in_stock": true,
"updated_at": "2026-05-24T09:30:00Z"
}'
Eine erfolgreiche Antwort enthält eine _id und ein result von created.
{
"_index": "products",
"_id": "wI4aQZkB8xExample",
"_version": 1,
"result": "created"
}
Automatische IDs eignen sich für Ereignisdaten, Protokolle, Klickaufzeichnungen und Append-Only-Inhalte. Sie sind nicht ideal, wenn dasselbe reale Element später erneut eintreffen könnte. Wenn dieselbe Produktaktualisierung zweimal mit automatischen IDs indiziert wird, erhalten Sie zwei Dokumente.
Indizieren mit eigener ID
Verwenden Sie PUT /{index}/_doc/{id}, wenn Ihr Quellsystem bereits eine stabile Kennung hat.
curl -X PUT "localhost:9200/products/_doc/sku-mouse-x1" \
-H "Content-Type: application/json" \
-d '{
"sku": "mouse-x1",
"name": "Wireless Mouse X1",
"price": 25.99,
"in_stock": true,
"updated_at": "2026-05-24T09:30:00Z"
}'
Wenn die ID nicht existiert, erstellt Elasticsearch sie. Wenn sie bereits existiert, ersetzt Elasticsearch das gesamte Dokument. Dieses Ersetzungsverhalten ist nützlich für einfache Synchronisierungsaufgaben, kann aber auch Felder löschen, die Sie vergessen haben zu senden.
Wenn das vorhandene Dokument beispielsweise category, brand und description enthält und Ihr nächster PUT nur price sendet, wird der gespeicherte _source nur die Felder dieser neuen Anfrage enthalten. Verwenden Sie PUT, wenn Sie das vollständige gewünschte Dokument senden.
Nur erstellen, wenn fehlend
Wenn eine doppelte Erstellung ein Fehler wäre, verwenden Sie den Create-Vorgang:
curl -X PUT "localhost:9200/products/_create/sku-mouse-x1" \
-H "Content-Type: application/json" \
-d '{
"sku": "mouse-x1",
"name": "Wireless Mouse X1",
"price": 25.99
}'
Wenn die ID bereits existiert, gibt Elasticsearch einen Versionskonflikt zurück, anstatt das Dokument zu überschreiben. Dies ist nützlich für Erfassungsaufgaben, bei denen das Wiederholen einer Nachricht einen vorhandenen Datensatz nicht ändern soll.
Felder teilweise aktualisieren
Verwenden Sie POST /{index}/_update/{id} mit einem doc-Objekt, wenn Sie nur einige Felder ändern möchten.
curl -X POST "localhost:9200/products/_update/sku-mouse-x1" \
-H "Content-Type: application/json" \
-d '{
"doc": {
"price": 22.49,
"in_stock": false,
"updated_at": "2026-05-24T10:15:00Z"
}
}'
Elasticsearch ruft intern das vorhandene Dokument ab, führt die bereitgestellten Felder zusammen und indiziert die geänderte Quelle erneut. Aus Sicht des API-Benutzers handelt es sich um eine partielle Aktualisierung, nicht um eine direkte Änderung auf der Festplatte.
Wenn das Dokument möglicherweise noch nicht existiert, verwenden Sie doc_as_upsert:
curl -X POST "localhost:9200/products/_update/sku-keyboard-k90" \
-H "Content-Type: application/json" \
-d '{
"doc": {
"sku": "keyboard-k90",
"name": "Mechanical Keyboard K90",
"price": 129.99,
"in_stock": true
},
"doc_as_upsert": true
}'
Dies erstellt das Dokument mit dem doc-Inhalt, wenn es fehlt. Verwenden Sie es, wenn Ihr vorgelagerter Feed "Aktueller Zustand"-Datensätze sendet und es Ihnen egal ist, ob dies das erste Mal ist, dass Elasticsearch die ID sieht.
Scriptbasierte Aktualisierungen
Skripte sind nützlich, wenn der neue Wert vom alten Wert abhängt. Ein häufiges Beispiel ist das Erhöhen eines Zählers:
curl -X POST "localhost:9200/products/_update/sku-mouse-x1" \
-H "Content-Type: application/json" \
-d '{
"script": {
"source": "ctx._source.views = (ctx._source.views ?: 0) + params.count",
"params": {
"count": 1
}
}
}'
Halten Sie Skripte klein und vorhersagbar. Sie sind leistungsstark, aber auch leichter falsch anzuwenden als eine einfache doc-Aktualisierung. Denken Sie bei hochvolumigen Zählern sorgfältig über Schreibrate, Aktualisierungsbedarf und darüber nach, ob Elasticsearch das System der Aufzeichnung sein sollte.
Bulk-Indizierung und -Aktualisierungen
Für mehr als eine Handvoll Dokumente verwenden Sie _bulk. Der Anforderungstext ist zeilenweise getrenntes JSON, und die letzte Zeile ist wichtig.
cat bulk-products.ndjson
{"index":{"_index":"products","_id":"sku-mouse-x1"}}
{"sku":"mouse-x1","name":"Wireless Mouse X1","price":25.99,"in_stock":true}
{"update":{"_index":"products","_id":"sku-keyboard-k90"}}
{"doc":{"price":119.99,"in_stock":true},"doc_as_upsert":true}
{"delete":{"_index":"products","_id":"sku-old-cable"}}
Senden Sie es so:
curl -X POST "localhost:9200/_bulk" \
-H "Content-Type: application/x-ndjson" \
--data-binary @bulk-products.ndjson
Verwenden Sie --data-binary, nicht einfaches -d, damit curl Zeilenumbrüche beibehält. Überprüfen Sie dann die Antwort. Eine Bulk-Anfrage kann HTTP 200 zurückgeben, während einzelne Elemente fehlgeschlagen sind.
curl -s -X POST "localhost:9200/_bulk" \
-H "Content-Type: application/x-ndjson" \
--data-binary @bulk-products.ndjson | jq '.errors, .items[] | select(.index.error or .update.error or .delete.error)'
Aktualisierung und Sichtbarkeit
Ein indiziertes Dokument ist nicht immer sofort durchsuchbar. Elasticsearch aktualisiert Indizes standardmäßig periodisch. Wenn Sie das Dokument nach ID lesen müssen, kann GET /products/_doc/sku-mouse-x1 es sofort finden. Wenn es in der Suche erscheinen soll, bevor Sie einen Test fortsetzen, verwenden Sie refresh=wait_for:
curl -X PUT "localhost:9200/products/_doc/sku-mouse-x1?refresh=wait_for" \
-H "Content-Type: application/json" \
-d '{"sku":"mouse-x1","name":"Wireless Mouse X1","price":25.99}'
Fügen Sie nicht bei jedem Produktionsschreiben erzwungene Aktualisierungen hinzu, ohne die Kosten zu messen. Sie können den Indizierungsdurchsatz verringern.
Eine praktische Faustregel
Verwenden Sie POST /_doc für Append-Only-Daten, bei denen doppelte Ereignisse akzeptabel oder anderweitig behandelt werden. Verwenden Sie PUT /_doc/{id}, wenn die Anfrage das vollständige aktuelle Dokument enthält. Verwenden Sie _update, wenn Sie nur bestimmte Felder ändern möchten. Verwenden Sie _create, wenn das Überschreiben ein Datenproblem verbergen würde. Verwenden Sie _bulk, wenn die Arbeit mehr als ein paar Dokumente umfasst.
Die meisten Elasticsearch-Indizierungsfehler entstehen durch die Wahl der falschen Schreibform. Der Endpunkt sollte zu Ihren Quelldaten, Ihrem Wiederholungsverhalten und der Frage passen, ob Elasticsearch einen vollständigen Datensatz oder eine durchsuchbare Kopie eines Datensatzes eines anderen Systems speichert.
Überprüfen Sie Mappings, bevor Sie die Schreibanfrage beschuldigen
Manchmal ist der Schreibvorgang erfolgreich, aber das Suchergebnis sieht trotzdem falsch aus. Das ist oft ein Mapping-Problem, kein Problem mit dem Indizierungsendpunkt.
Überprüfen Sie das Mapping:
curl -s "localhost:9200/products/_mapping?pretty"
Wenn price zuerst als Text indiziert wurde, weil ein frühes Testdokument "25.99" als Zeichenfolge gesendet hat, können Bereichsabfragen sich schlecht verhalten. Wenn sku exakte Übereinstimmung und Aggregationen erfordert, sollte es normalerweise ein keyword-Feld sein oder ein Keyword-Unterfeld haben. Wenn Zeitstempel in unterschiedlichen Formaten eintreffen, können einige Dokumente während der Indizierung abgelehnt werden, während andere erfolgreich sind.
Erstellen Sie für vorhersagbare Systeme das Index-Mapping vor dem ersten Schreibvorgang:
curl -X PUT "localhost:9200/products" \
-H "Content-Type: application/json" \
-d '{
"mappings": {
"properties": {
"sku": { "type": "keyword" },
"name": { "type": "text" },
"price": { "type": "double" },
"in_stock": { "type": "boolean" },
"updated_at": { "type": "date" }
}
}
}'
Dynamisches Mapping ist praktisch für die Erkundung. Für die Produktionserfassung verhindern explizite Mappings, dass ein schlechtes erstes Dokument den Index formt.
Behandeln Sie Konflikte und Wiederholungen bewusst
Gleichzeitige Aktualisierungen können zu Konflikten führen. Wenn zwei Worker fast gleichzeitig dasselbe Dokument aktualisieren, basiert möglicherweise eines auf einer älteren Version. Für einfache Aktualisierungswiederholungen unterstützt Elasticsearch retry_on_conflict:
curl -X POST "localhost:9200/products/_update/sku-mouse-x1?retry_on_conflict=3" \
-H "Content-Type: application/json" \
-d '{
"doc": {
"price": 21.99
}
}'
Das ist nützlich für risikoarme Aktualisierungen, aber kein Ersatz für klare Zuständigkeiten. Wenn ein System Produktnamen und ein anderes den Bestand verwaltet, sollten Sie erwägen, verschiedene Felder durch klar definierte Pipelines zu aktualisieren. Wenn die Reihenfolge der Ereignisse wichtig ist, fügen Sie Quellzeitstempel hinzu und lehnen Sie ältere Aktualisierungen in Ihrer Erfassungsschicht oder mit einem sorgfältigen Skript ab.
Lesen nach Schreiben während des Debuggens
Wenn Sie einen Indizierungsablauf testen, rufen Sie das Dokument sofort nach ID ab:
curl -s "localhost:9200/products/_doc/sku-mouse-x1?pretty"
Suchen Sie dann danach:
curl -s "localhost:9200/products/_search?pretty" \
-H "Content-Type: application/json" \
-d '{
"query": {
"term": {
"sku": "mouse-x1"
}
}
}'
Wenn GET nach ID funktioniert, die Suche jedoch nicht, denken Sie an Aktualisierung, Mapping, Analyzer oder Abfragetyp. Wenn beides fehlschlägt, denken Sie an Indizierungsfehler, falschen Index, falsche ID, Authentifizierung oder Routing.
Protokollieren Sie für Anwendungen den Zielindex, die Dokument-ID, den Antwortstatus und die Elementfehler auf Bulk-Ebene. Sie müssen nicht jedes vollständige Dokument für immer protokollieren, aber während der Einführung sparen diese Felder Stunden.