RousselTMLEARNING

Observabilité

Query DSL et agrégations avancées Elasticsearch, avec ES|QL

Écrire des requêtes Elasticsearch avancées : bool, filter et score, nested, function_score et pertinence BM25, agrégations bucket, metrics et pipeline, composite, et le langage ES|QL.

1. La requête bool #

La base de tout.

Score et filtre #

Clauses de la requête bool
GET products/_search
{
  "query": { "bool": {
    "must":     [ { "match": { "name": { "query": "chaussure trail", "operator": "and" } } } ],
    "should":   [ { "term": { "brand": { "value": "acme", "boost": 2 } } } ],
    "filter":   [ { "term": { "in_stock": true } }, { "range": { "price": { "lte": 150 } } } ],
    "must_not": [ { "term": { "status": "discontinued" } } ]
  } }
}
Bonne Pratique : Tout ce qui est oui/non (statut, plage de dates, client) va dans filter : plus rapide, mis en cache, et n'altère pas la pertinence.

2. Pertinence #

Comprendre et ajuster le score.

Outils #

  • Le score par défaut est BM25 : fréquence du terme dans le document, rareté dans l'index, longueur du champ.
  • "explain": true détaille le calcul pour un document.
  • function_score combine le score textuel avec la popularité, la fraîcheur (gauss sur une date) ou la distance.
  • nested interroge chaque objet d'un tableau séparément (sinon « taille 42 » et « couleur rouge » peuvent venir de deux lignes différentes).

3. Agrégations #

Analyser, pas seulement chercher.

Exemples #

GET logs-nginx-*/_search
{
  "size": 0,
  "query": { "range": { "@timestamp": { "gte": "now-24h" } } },
  "aggs": {
    "par_heure": {
      "date_histogram": { "field": "@timestamp", "fixed_interval": "1h" },
      "aggs": {
        "erreurs":   { "filter": { "range": { "http.response.status_code": { "gte": 500 } } } },
        "p95":       { "percentiles": { "field": "event.duration", "percents": [ 95 ] } },
        "taux":      { "bucket_script": { "buckets_path": { "e": "erreurs>_count", "t": "_count" }, "script": "params.e / params.t * 100" } }
      }
    },
    "top_paths": { "terms": { "field": "url.path", "size": 10 } },
    "visiteurs": { "cardinality": { "field": "source.ip" } }
  }
}
À savoir : cardinality est approximatif (HyperLogLog) ; composite permet de paginer sur toutes les combinaisons d'une agrégation, contrairement à terms.

ES|QL #

FROM logs-nginx-*
| WHERE @timestamp > NOW() - 24 hours AND http.response.status_code >= 500
| STATS erreurs = COUNT(*) BY url.path
| SORT erreurs DESC
| LIMIT 10

Articles liés

Architecture distribuée Elasticsearch : rôles des nœuds, shards, répliques et allocation

Comprendre le fonctionnement distribué d'Elasticsearch : rôles des nœuds, nœuds master et quorum, cluster sta…

Mappings et analyse de texte Elasticsearch : types de champs, analyseurs et mapping dynamique

Maîtriser les mappings Elasticsearch : types de champs (text, keyword, numériques, date, ip, nested), multi-f…

Ingestion Elasticsearch : Bulk API, ingest pipelines, enrich et reindex

Ingérer et transformer des données dans Elasticsearch : Bulk API, ingest pipelines et processeurs (grok, diss…

Pour aller plus loin