1. Declaring your indexes #
Template and mapping.
An index template #
Declare types before the first write: an existing field type cannot change without reindexing.
curl -sk -u 'admin:Str0ng!Passw0rd-2026' -H 'Content-Type: application/json' -X PUT https://localhost:9200/_index_template/logs_app -d '{
"index_patterns": ["logs-app-*"],
"template": {
"settings": {"number_of_shards": 1, "number_of_replicas": 0},
"mappings": {"properties": {
"@timestamp": {"type": "date"},
"level": {"type": "keyword"},
"service": {"type": "keyword"},
"message": {"type": "text"},
"duree_ms": {"type": "integer"}
}}
}
}'| Type | For | Search |
|---|---|---|
keyword | Exact value: level, service | Filter, aggregation, sort |
text | Free text: message | Full text, analyzed |
date, integer, ip | Typed values | Ranges, aggregations, CIDR |
2. Indexing #
The bulk API.
Writing in batches #
cat > lot.ndjson <<'EOF'
{"index":{"_index":"logs-app-000001"}}
{"@timestamp":"2026-11-04T10:00:00Z","level":"ERROR","service":"paiement","message":"timeout vers la banque utilisateur=alice","duree_ms":3100}
{"index":{"_index":"logs-app-000001"}}
{"@timestamp":"2026-11-04T10:00:01Z","level":"INFO","service":"paiement","message":"paiement accepté","duree_ms":120}
{"index":{"_index":"logs-app-000001"}}
{"@timestamp":"2026-11-04T10:00:02Z","level":"INFO","service":"panier","message":"article ajouté","duree_ms":40}
EOF
curl -sk -u 'admin:Str0ng!Passw0rd-2026' -H 'Content-Type: application/x-ndjson' \
-X POST 'https://localhost:9200/_bulk?refresh=true' --data-binary @lot.ndjsonBest practice: always use_bulkfor large volumes, and read"errors"in the response: the HTTP code stays 200 even when documents are refused. Avoidrefresh=truein production; here it lets you read the result immediately.
3. Searching #
Query DSL, aggregations, PPL and SQL.
Search #
In a bool, must counts towards the score, while filter only says yes or no, and is cached. Put in filter everything that does not need relevance.
curl -sk -u 'admin:Str0ng!Passw0rd-2026' -H 'Content-Type: application/json' -X POST 'https://localhost:9200/logs-app-*/_search' -d '{
"query": {"bool": {
"must": [{"match": {"message": "banque"}}],
"filter": [{"term": {"service": "paiement"}}]
}}
}'Aggregations #
curl -sk -u 'admin:Str0ng!Passw0rd-2026' -H 'Content-Type: application/json' -X POST 'https://localhost:9200/logs-app-*/_search' -d '{
"size": 0,
"aggs": {"par_service": {
"terms": {"field": "service"},
"aggs": {"p95": {"percentiles": {"field": "duree_ms", "percents": [95]}}}
}}
}'Result of our test: paiement has 2 documents (p95 of 3100 ms) and panier 1 (p95 of 40 ms).
PPL and SQL #
To explore logs, PPL chains operations with |, like a shell.
curl -sk -u 'admin:Str0ng!Passw0rd-2026' -H 'Content-Type: application/json' -X POST https://localhost:9200/_plugins/_ppl \
-d '{"query":"source=logs-app-* | where service=\"paiement\" | stats count() by level"}'
curl -sk -u 'admin:Str0ng!Passw0rd-2026' -H 'Content-Type: application/json' -X POST https://localhost:9200/_plugins/_sql \
-d '{"query":"SELECT service, COUNT(*) n FROM logs-app-000001 GROUP BY service"}'My progress
Sign in to track your progress and take notes. Sign in
Recommended Articles
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 per...
OpenSearch Dashboards, alerting and observability
Explore data in OpenSearch Dashboards, create alert monitors and discover Trace Analytics, Event ...
Installing OpenSearch and OpenSearch Dashboards
Install OpenSearch with Docker Compose or the archive: initial password, vm.max_map_count, demo c...
Feeding OpenSearch: ingest pipelines and Data Prepper
Transform data with ingest pipelines, collect with Data Prepper, receive OTLP and avoid the dynam...
Data streams et templates Elasticsearch : component templates, index templates et séries temporelles
Gérer les données horodatées avec les data streams : index templates et component templates, conv...
Exploring data in OpenObserve: SQL, PromQL and VRL
Search with SQL, query metrics with PromQL, optimize a stream (indexes, partitions, retention) an...
Bonnes pratiques Elasticsearch : mappings, shards, cycle de vie et exploitation
Bonnes pratiques Elasticsearch : dimensionnement des shards, mappings explicites, templates, ILM,...
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, nest...
OpenSearch: concepts, architecture and differences with Elasticsearch
Understanding OpenSearch: project origin, license, differences with Elasticsearch, indexes, shard...