Elasticsearch-Spickzettel: Wesentliche Befehle und Tipps

Elasticsearch-Befehle für Suche, Indexierung und Analyse

Inhaltsverzeichnis

Elasticsearch ist ein leistungsstarker, verteilter Such- und Analyse-Engine, der auf Apache Lucene aufgebaut ist. Dieses umfassende CheatSheet deckt essentielle Befehle, bewährte Praktiken und Schnellreferenzen für die Arbeit mit Elasticsearch-Clustern ab.

elasticsearch

Hinweis: Die meisten Beispiele in diesem Leitfaden verwenden cURL für HTTP-Anfragen. Wenn Sie neu in der Verwendung von cURL sind oder eine Schnellreferenz für fortgeschrittene Optionen benötigen, finden Sie in unserem cURL CheatSheet detaillierte Techniken für HTTP-Anfragen auf der Kommandozeile.

Cluster-Verwaltung

Cluster-Gesundheitszustand prüfen

Alle Befehle in diesem Abschnitt verwenden cURL, um mit der REST-API von Elasticsearch zu interagieren. Sie können diese Anfragen nach Bedarf mit zusätzlichen Headern, Authentifizierung und anderen Optionen anpassen.

# Grundlegender Gesundheitscheck
curl -X GET "localhost:9200/_cluster/health?pretty"

# Detaillierter Cluster-Gesundheitszustand mit Shard-Informationen
curl -X GET "localhost:9200/_cluster/health?level=shards&pretty"

# Knoteninformationen prüfen
curl -X GET "localhost:9200/_cat/nodes?v"

# Cluster-Einstellungen prüfen
curl -X GET "localhost:9200/_cluster/settings?pretty"

Knoten-Operationen

# Alle Knoten auflisten
curl -X GET "localhost:9200/_cat/nodes?v&h=name,node.role,heap.percent,ram.percent,cpu,load_1m"

# Knotenstatistiken
curl -X GET "localhost:9200/_nodes/stats?pretty"

# Hot Threads (Fehlerbehebung)
curl -X GET "localhost:9200/_nodes/hot_threads"

Index-Verwaltung

Indizes erstellen und löschen

# Index erstellen
curl -X PUT "localhost:9200/my_index?pretty"

# Index mit Einstellungen erstellen
curl -X PUT "localhost:9200/my_index" -H 'Content-Type: application/json' -d'
{
  "settings": {
    "number_of_shards": 3,
    "number_of_replicas": 1
  }
}
'

# Index löschen
curl -X DELETE "localhost:9200/my_index?pretty"

# Alle Indizes auflisten
curl -X GET "localhost:9200/_cat/indices?v"

# Indexstatistiken
curl -X GET "localhost:9200/my_index/_stats?pretty"

Index-Mappings

# Mapping definieren
curl -X PUT "localhost:9200/products" -H 'Content-Type: application/json' -d'
{
  "mappings": {
    "properties": {
      "name": { "type": "text" },
      "price": { "type": "float" },
      "created_at": { "type": "date" },
      "tags": { "type": "keyword" },
      "description": { 
        "type": "text",
        "analyzer": "english"
      }
    }
  }
}
'

# Mapping abrufen
curl -X GET "localhost:9200/products/_mapping?pretty"

# Mapping aktualisieren (Feld hinzufügen)
curl -X PUT "localhost:9200/products/_mapping" -H 'Content-Type: application/json' -d'
{
  "properties": {
    "category": { "type": "keyword" }
  }
}
'

Index-Vorlagen

# Index-Vorlage erstellen
curl -X PUT "localhost:9200/_index_template/logs_template" -H 'Content-Type: application/json' -d'
{
  "index_patterns": ["logs-*"],
  "template": {
    "settings": {
      "number_of_shards": 1
    },
    "mappings": {
      "properties": {
        "timestamp": { "type": "date" },
        "message": { "type": "text" },
        "level": { "type": "keyword" }
      }
    }
  }
}
'

# Vorlagen auflisten
curl -X GET "localhost:9200/_index_template?pretty"

Dokumentoperationen (CRUD)

Dokumente erstellen

# Dokument mit automatisch generierter ID indexieren
curl -X POST "localhost:9200/products/_doc?pretty" -H 'Content-Type: application/json' -d'
{
  "name": "Laptop",
  "price": 999.99,
  "tags": ["electronics", "computers"]
}
'

# Dokument mit spezifischer ID indexieren
curl -X PUT "localhost:9200/products/_doc/1?pretty" -H 'Content-Type: application/json' -d'
{
  "name": "Laptop",
  "price": 999.99
}
'

# Massenindexierung (Bulk)
curl -X POST "localhost:9200/_bulk?pretty" -H 'Content-Type: application/json' -d'
{ "index": { "_index": "products", "_id": "1" }}
{ "name": "Laptop", "price": 999.99 }
{ "index": { "_index": "products", "_id": "2" }}
{ "name": "Mouse", "price": 29.99 }
'

Dokumente lesen

# Dokument nach ID abrufen
curl -X GET "localhost:9200/products/_doc/1?pretty"

# Mehrere Dokumente abrufen
curl -X GET "localhost:9200/_mget?pretty" -H 'Content-Type: application/json' -d'
{
  "docs": [
    { "_index": "products", "_id": "1" },
    { "_index": "products", "_id": "2" }
  ]
}
'

# Prüfen, ob ein Dokument existiert
curl -I "localhost:9200/products/_doc/1"

Dokumente aktualisieren

# Dokument aktualisieren
curl -X POST "localhost:9200/products/_update/1?pretty" -H 'Content-Type: application/json' -d'
{
  "doc": {
    "price": 899.99
  }
}
'

# Aktualisierung mit Skript
curl -X POST "localhost:9200/products/_update/1?pretty" -H 'Content-Type: application/json' -d'
{
  "script": {
    "source": "ctx._source.price *= params.discount",
    "params": {
      "discount": 0.9
    }
  }
}
'

# Upsert (Aktualisieren oder Einfügen)
curl -X POST "localhost:9200/products/_update/1?pretty" -H 'Content-Type: application/json' -d'
{
  "doc": {
    "price": 899.99
  },
  "doc_as_upsert": true
}
'

Dokumente löschen

# Löschen nach ID
curl -X DELETE "localhost:9200/products/_doc/1?pretty"

# Löschen nach Abfrage
curl -X POST "localhost:9200/products/_delete_by_query?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "match": {
      "name": "old"
    }
  }
}
'

Suchabfragen

Basis-Suche

# Alle Treffer
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "match_all": {}
  }
}
'

# Match-Abfrage
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "match": {
      "name": "laptop"
    }
  }
}
'

# Multi-Match-Abfrage
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "multi_match": {
      "query": "laptop gaming",
      "fields": ["name", "description"]
    }
  }
}
'

Term-Ebene Abfragen

# Term-Abfrage (exakte Übereinstimmung)
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "term": {
      "tags": "electronics"
    }
  }
}
'

# Terms-Abfrage (mehrere Werte)
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "terms": {
      "tags": ["electronics", "computers"]
    }
  }
}
'

# Bereichs-Abfrage
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "range": {
      "price": {
        "gte": 100,
        "lte": 1000
      }
    }
  }
}
'

# Exists-Abfrage
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "exists": {
      "field": "description"
    }
  }
}
'

Boolesche Abfragen

# Bool-Abfrage (must, should, must_not, filter)
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "bool": {
      "must": [
        { "match": { "name": "laptop" }}
      ],
      "filter": [
        { "range": { "price": { "gte": 500 }}}
      ],
      "should": [
        { "term": { "tags": "gaming" }}
      ],
      "must_not": [
        { "term": { "tags": "refurbished" }}
      ]
    }
  }
}
'

Erweiterte Suche

# Wildcard-Abfrage
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "wildcard": {
      "name": "lap*"
    }
  }
}
'

# Fuzzy-Abfrage (Toleranz gegenüber Tippfehlern)
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "fuzzy": {
      "name": {
        "value": "laptpo",
        "fuzziness": "AUTO"
      }
    }
  }
}
'

# Prefix-Abfrage
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "prefix": {
      "name": "lap"
    }
  }
}
'

Aggregationen

Metrik-Aggregationen

# Durchschnitt, Summe, Minimum, Maximum
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "size": 0,
  "aggs": {
    "avg_price": { "avg": { "field": "price" }},
    "max_price": { "max": { "field": "price" }},
    "min_price": { "min": { "field": "price" }},
    "total_sales": { "sum": { "field": "price" }}
  }
}
'

# Stats-Aggregation
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "size": 0,
  "aggs": {
    "price_stats": {
      "stats": { "field": "price" }
    }
  }
}
'

Bucket-Aggregationen

# Terms-Aggregation (Gruppierung)
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "size": 0,
  "aggs": {
    "popular_tags": {
      "terms": {
        "field": "tags",
        "size": 10
      }
    }
  }
}
'

# Bereichs-Aggregation
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "size": 0,
  "aggs": {
    "price_ranges": {
      "range": {
        "field": "price",
        "ranges": [
          { "to": 50 },
          { "from": 50, "to": 100 },
          { "from": 100 }
        ]
      }
    }
  }
}
'

# Datums-Histogramm
curl -X GET "localhost:9200/logs/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "size": 0,
  "aggs": {
    "logs_over_time": {
      "date_histogram": {
        "field": "timestamp",
        "calendar_interval": "day"
      }
    }
  }
}
'

Verschachtelte Aggregationen

# Verschachtelte Aggregationen
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "size": 0,
  "aggs": {
    "categories": {
      "terms": { "field": "category" },
      "aggs": {
        "avg_price": {
          "avg": { "field": "price" }
        }
      }
    }
  }
}
'

Sortierung und Paginierung

# Nach Feld sortieren
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": { "match_all": {} },
  "sort": [
    { "price": { "order": "desc" }},
    { "_score": { "order": "desc" }}
  ]
}
'

# Paginierung mit from/size
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "from": 0,
  "size": 10,
  "query": { "match_all": {} }
}
'

# Suche nach (für tiefe Paginierung)
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "size": 10,
  "query": { "match_all": {} },
  "sort": [{ "price": "asc" }, { "_id": "asc" }],
  "search_after": [100, "product_123"]
}
'

Feldauswahl und Hervorhebung

# Spezifische Felder auswählen
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": { "match_all": {} },
  "_source": ["name", "price"]
}
'

# Hervorhebung (Highlighting)
curl -X GET "localhost:9200/products/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "match": { "description": "gaming laptop" }
  },
  "highlight": {
    "fields": {
      "description": {}
    }
  }
}
'

Index-Aliase

# Alias erstellen
curl -X POST "localhost:9200/_aliases?pretty" -H 'Content-Type: application/json' -d'
{
  "actions": [
    { "add": { "index": "products_v1", "alias": "products" }}
  ]
}
'

# Alias auf neuen Index wechseln (ohne Downtime)
curl -X POST "localhost:9200/_aliases?pretty" -H 'Content-Type: application/json' -d'
{
  "actions": [
    { "remove": { "index": "products_v1", "alias": "products" }},
    { "add": { "index": "products_v2", "alias": "products" }}
  ]
}
'

# Aliase auflisten
curl -X GET "localhost:9200/_cat/aliases?v"

Reindex

# Reindex von einem Index zum anderen
curl -X POST "localhost:9200/_reindex?pretty" -H 'Content-Type: application/json' -d'
{
  "source": {
    "index": "old_products"
  },
  "dest": {
    "index": "new_products"
  }
}
'

# Reindex mit Abfrage
curl -X POST "localhost:9200/_reindex?pretty" -H 'Content-Type: application/json' -d'
{
  "source": {
    "index": "products",
    "query": {
      "range": {
        "price": { "gte": 100 }
      }
    }
  },
  "dest": {
    "index": "expensive_products"
  }
}
'

Snapshots und Backups

# Snapshot-Repository registrieren
curl -X PUT "localhost:9200/_snapshot/my_backup?pretty" -H 'Content-Type: application/json' -d'
{
  "type": "fs",
  "settings": {
    "location": "/mount/backups/my_backup"
  }
}
'

# Snapshot erstellen
curl -X PUT "localhost:9200/_snapshot/my_backup/snapshot_1?wait_for_completion=true&pretty"

# Snapshot wiederherstellen
curl -X POST "localhost:9200/_snapshot/my_backup/snapshot_1/_restore?pretty"

# Snapshots auflisten
curl -X GET "localhost:9200/_snapshot/my_backup/_all?pretty"

# Snapshot löschen
curl -X DELETE "localhost:9200/_snapshot/my_backup/snapshot_1?pretty"

Leistungsoptimierung

Index-Einstellungen

# Refresh während der Massenindexierung deaktivieren
curl -X PUT "localhost:9200/products/_settings?pretty" -H 'Content-Type: application/json' -d'
{
  "index": {
    "refresh_interval": "-1"
  }
}
'

# Nach der Massenindexierung wieder aktivieren
curl -X PUT "localhost:9200/products/_settings?pretty" -H 'Content-Type: application/json' -d'
{
  "index": {
    "refresh_interval": "1s"
  }
}
'

# Force Merge (Optimierung)
curl -X POST "localhost:9200/products/_forcemerge?max_num_segments=1&pretty"

Cache leeren

# Alle Caches leeren
curl -X POST "localhost:9200/_cache/clear?pretty"

# Spezifischen Cache leeren
curl -X POST "localhost:9200/products/_cache/clear?query=true&pretty"

Überwachung und Fehlerbehebung

# Wartende Aufgaben
curl -X GET "localhost:9200/_cat/pending_tasks?v"

# Thread-Pool-Statistiken
curl -X GET "localhost:9200/_cat/thread_pool?v"

# Segment-Informationen
curl -X GET "localhost:9200/_cat/segments?v"

# Wiederherstellungs-Informationen
curl -X GET "localhost:9200/_cat/recovery?v&h=index,stage,time"

# Tasks-API
curl -X GET "localhost:9200/_tasks?detailed=true&pretty"

Python-Client-Beispiele

from elasticsearch import Elasticsearch

# Verbindung zu Elasticsearch herstellen
es = Elasticsearch(['http://localhost:9200'])

# Dokument indexieren
doc = {
    'name': 'Laptop',
    'price': 999.99,
    'tags': ['electronics']
}
es.index(index='products', id=1, document=doc)

# Suche
resp = es.search(index='products', query={'match': {'name': 'laptop'}})
for hit in resp['hits']['hits']:
    print(hit['_source'])

# Massenindexierung
from elasticsearch.helpers import bulk

actions = [
    {
        '_index': 'products',
        '_id': i,
        '_source': {'name': f'Product {i}', 'price': i * 10}
    }
    for i in range(1000)
]
bulk(es, actions)

JavaScript/Node.js-Client-Beispiele

Der JavaScript-Client von Elasticsearch bietet eine typsichere Möglichkeit, mit Ihrem Cluster zu interagieren. Für produktive Anwendungen ist die Verwendung von TypeScript zur besseren Typsicherheit und Autovervollständigung ratsam. Siehe unser TypeScript CheatSheet für bewährte Praktiken bezüglich Typdefinitionen und Schnittstellen.

const { Client } = require('@elastic/elasticsearch');
const client = new Client({ node: 'http://localhost:9200' });

// Dokument indexieren
async function indexDoc() {
  await client.index({
    index: 'products',
    id: 1,
    document: {
      name: 'Laptop',
      price: 999.99
    }
  });
}

// Suche
async function search() {
  const result = await client.search({
    index: 'products',
    query: {
      match: { name: 'laptop' }
    }
  });
  console.log(result.hits.hits);
}

// Massenindexierung
async function bulkIndex() {
  const operations = [];
  for (let i = 0; i < 1000; i++) {
    operations.push({ index: { _index: 'products', _id: i } });
    operations.push({ name: `Product ${i}`, price: i * 10 });
  }
  await client.bulk({ operations });
}

TypeScript-Beispiel mit starker Typisierung

import { Client } from '@elastic/elasticsearch';

interface Product {
  name: string;
  price: number;
  tags?: string[];
  created_at?: Date;
}

const client = new Client({ node: 'http://localhost:9200' });

async function indexProduct(product: Product, id: number): Promise<void> {
  await client.index<Product>({
    index: 'products',
    id: id.toString(),
    document: product
  });
}

async function searchProducts(query: string): Promise<Product[]> {
  const result = await client.search<Product>({
    index: 'products',
    query: {
      match: { name: query }
    }
  });
  
  return result.hits.hits.map(hit => hit._source as Product);
}

Bewährte Praktiken

Index-Design

  • Halten Sie die Shard-Größe zwischen 20 und 50 GB für optimale Leistung
  • Verwenden Sie Index-Lebenszyklus-Management (ILM) für Zeitreihendaten
  • Entwerfen Sie Mappings sorgfältig, bevor Sie Daten indexieren
  • Verwenden Sie geeignete Feldtypen (keyword vs. text, Datumsformate)
  • Deaktivieren Sie _source für große Dokumente, falls nicht benötigt

Abfrage-Optimierung

  • Verwenden Sie Filter anstelle von Abfragen, wenn kein Scoring benötigt wird
  • Bevorzugen Sie Term-Ebene-Abfragen für strukturierte Daten
  • Verwenden Sie bool-Abfragen, um mehrere Bedingungen effizient zu kombinieren
  • Implementieren Sie Paginierung mit search_after für tiefe Paginierung
  • Cachen Sie häufig verwendete Filter

Indexierungs-Leistung

  • Verwenden Sie die Bulk-API für Batch-Indexierung (1000–5000 Dokumente pro Anfrage)
  • Deaktivieren Sie Refresh während Bulk-Operationen
  • Erhöhen Sie index.refresh_interval während intensiver Indexierung
  • Verwenden Sie mehrere Threads/Worker für parallele Indexierung
  • Erwägen Sie Routing für eine bessere Shard-Verteilung

Cluster-Verwaltung

  • Überwachen Sie den Cluster-Gesundheitszustand regelmäßig
  • Richten Sie eine korrekte Replikakonfiguration ein
  • Verwenden Sie dedizierte Master-Knoten für große Cluster
  • Implementieren Sie eine geeignete Backup-Strategie mit Snapshots
  • Überwachen Sie die JVM-Heap-Nutzung (unter 75% halten)

Sicherheit

  • Aktivieren Sie Authentifizierung und Autorisierung (X-Pack Security)
  • Verwenden Sie HTTPS für Produktionsbereitstellungen (konfigurieren Sie cURL mit den Optionen --cacert, --cert und --key für SSL/TLS)
  • Implementieren Sie eine geeignete rollenbasierte Zugriffskontrolle
  • Regelmäßige Sicherheitsupdates und Patches
  • Verschlüsselung von Daten im Ruhezustand und während der Übertragung

Gängige Anwendungsfälle

Volltextsuche

Elasticsearch excelliert bei der Volltextsuche mit Funktionen wie:

  • Relevanz-Scoring
  • Fuzzy-Matching
  • Phrasen-Matching
  • Synonym-Handling
  • Unterstützung mehrerer Sprachen Wenn Sie evaluieren, ob Sie die Suche in Postgres behalten oder zu einer dedizierten Suchmaschine migrieren sollen, erklärt dieser Vergleich von PostgreSQL-Volltextsuche und Elasticsearch die praktischen Kompromisse.

Log-Analyse (ELK-Stack)

  • Sammeln von Logs mit Logstash/Filebeat
  • Indexierung und Suche von Logs in Elasticsearch
  • Visualisierung mit Kibana-Dashboards
  • Einrichtung von Alarmen für Anomalien

E-Commerce-Suche

  • Suche im Produktkatalog
  • Facettierte Navigation mit Aggregationen
  • Autovervollständigung und Vorschläge
  • Personalisierte Suchergebnisse

Überwachung der Anwendungsleistung

  • Indexierung von Anwendungs-Metriken
  • Echtzeit-Überwachungs-Dashboards
  • Anomalie-Erkennung
  • Analyse von Leistungstrends

Offizielle Elasticsearch-Ressourcen

Verwandte CheatSheets und Leitfäden

Abonnieren

Neue Beiträge zu Systemen, Infrastruktur und KI-Engineering.