Votre client ne voit pas la différence.
Pas un nouveau SDK, pas un dialecte « en grande partie compatible » : les bibliothèques officielles d’Elasticsearch s’y connectent, la poignée de main qu’elles font à la connexion réussit, et les requêtes que vous envoyez déjà reviennent dans la forme qu’elles savent déjà lire.
L’index inversé lui-même n’est pas réinventé — c’est Tantivy, l’équivalent Rust de Lucene. Le travail est la couche de compatibilité au-dessus, et elle est vérifiée plutôt qu’affirmée : la suite de tests REST d’Elastic elle-même est rejouée contre un build qui tourne, cas par cas, et ce qu’elle a trouvé est le chiffre ci-dessous — ni un objectif, ni une promesse.
from elasticsearch import Elasticsearch # the official client, unmodified
es = Elasticsearch("http://localhost:9200")
es.indices.create(index="books", mappings={"properties": {
"title": {"type": "text"}, "author": {"type": "keyword"},
"year": {"type": "integer"}}})
es.index(index="books", id="1", refresh=True,
document={"title": "Bel-Ami", "author": "Maupassant", "year": 1885})
es.search(index="books", query={"match": {"title": "bel ami"}})
# {'took': 3, 'hits': {'total': {'value': 1, 'relation': 'eq'}, ...conformité mesurée
mesurée le 1er septembre 2026 · il y a 58 jours
vieux de plus d’un mois
Cette mesure date de 58 jours — au-delà des 30 jours après lesquels cette page cesse de la présenter comme l’état actuel. Lisez-la comme un instantané pris le 1er septembre 2026, et consultez le rapport pour savoir où on en est.
82,7 %
172 / 208 cas — fidélité dans le périmètre déclaré
Parmi les cas qui portent sur quelque chose que cette page affirme, la part qui répond exactement comme Elasticsearch : 172 sur 208. Les cas qui échouent sur une capacité que le dépôt déclare refusée sortent de ce dénominateur — c’est le prix du périmètre, et la liste ci-dessous les nomme tous.
14,7 %
172 / 1 173 cas — de la suite d’Elasticsearch elle-même
Les mêmes 172 cas, rapportés à toute la suite que publie Elastic : 1 173. C’est la part d’Elasticsearch couverte tout court — une fraction, et le chiffre qui garde le premier honnête.
- ce qui a tourné
- La suite REST d’Elastic elle-même, version 7.10.2 (Apache-2.0), rejouée sans modification contre un build qui tourne — 1 173 cas répartis en 107 suites. Pas des tests écrits ici pour passer ici.
- contre
ferrite-0.10.0, qui annonce la version d’API 8.15.0, mesuré le 1er septembre 2026.- déclaré
- 215 capacités dans
compat.yaml: 103 supportées, 68 partielles, 44 refusées — les deux listes de cette page en sont générées. - rapport brut
- docs/conformance.json — chaque cas, son verdict et sa raison. docs/compat.md en est l’équivalent pour les capacités.
dans le périmètre
Généré depuis le compat.yaml du dépôt, une ligne par table : 103 capacités supportées et 68 partielles — les partielles sont marquées, parce qu’une capacité dont les bords manquent n’est pas une capacité sur laquelle on peut compter. Chacune est nommée comme le dépôt la nomme.
- cluster
GET /·HEAD /(ping) ·GET /_cluster/health,/_cluster/health/{index}partiel ·GET /_cat/indices,/_cat/indices/{index}partiel ·GET /_cat/healthpartiel ·GET /_nodes,/_nodes/{spec}partiel ·Content-Encoding: gzip/deflatesur le corps d'une requête- index
- Création à l'écriture · Expressions d'index (
a,b,logs-*,_all, exclusions, alias) ·PUT /{index}partiel ·DELETE /{index}·HEAD /{index}·GET /{index}·GET /{index}/_mapping·GET /{index}/_settingspartiel ·PUT /{index}/_settingspartiel ·PUT /{index}/_mappingpartiel ·POST /{index}/_refresh·POST|GET /_analyze,/{index}/_analyzepartiel · Mapping dynamique · Alias · Templates d'index —_index_templateet_templatepartiel ·GET /{index}/_statspartiel - analyzers
standard(défaut) ·simple·whitespace·keyword·stop·english·french·snowball·danish,dutch,german,hungarian,italian,norwegian,portuguese,romanian,russian,spanish,swedish,turkish· Analyzers sur mesure (settings.analysis)- analyse sur mesure
analysis.analyzerde typecustom· Tokenizerspartiel ·ngrametedge_ngram— tokenizer et filtre · Filtrespartiel- types de champ
text·keyword·byte,short,integer,long·float,doublepartiel ·boolean·datepartiel · Tableaux de valeurs ·null·object(sous-objet), déclaré ou deviné ·nestedpartiel ·join(parent/enfant)partiel ·analyzerpartiel ·search_analyzer·copy_to·storepartiel · Multi-fields (fields) ·ignore_above·index- ingestion
PUT|POST /{index}/_doc/{id}partiel ·POST /{index}/_doc·PUT|POST /{index}/_create/{id}·GET /{index}/_doc/{id}·HEAD /{index}/_doc/{id}·DELETE /{index}/_doc/{id}·POST|PUT /_bulk,/{index}/_bulkpartiel ·refresh(true/false/wait_for) ·POST /{index}/_update/{id}partiel ·GET|POST /_mget,/{index}/_mget·GET|POST /{index}/_count· Versionnage optimisteif_seq_no/if_primary_term·POST /{index}/_delete_by_querypartiel ·POST /{index}/_update_by_querypartiel- scroll
?scroll=1msur_search·POST|GET /_search/scroll·POST|GET /_search/scroll/{scroll_id}·DELETE /_search/scroll,/_search/scroll/{scroll_id}- motifs d’index
catalogue·produits,marques·audits-2026.08.*·_all,*, URL sans index ·audits-*,-audits-2026.07.*·ignore_unavailable·allow_no_indices·expand_wildcardspartiel- alias
POST /_aliasespartiel ·PUT|POST /{index}/_alias/{nom}et ses six autres URL (/_alias/{nom},/{index}/_alias,/_alias,_aliasespour chacune) ·DELETE /{index}/_alias/{nom}·GET /_alias,/_alias/{nom},/{index}/_alias,/{index}/_alias/{nom}·HEAD /_alias/{nom},/{index}/_alias/{nom}·aliasesdansPUT /{index}·is_write_index- réglages du cluster
GET|PUT /_cluster/settingspartiel ·action.destructive_requires_name- query DSL
match_all·match_none·matchpartiel ·multi_matchpartiel ·match_phrasepartiel ·match_phrase_prefixpartiel ·existspartiel ·term·ids·prefixpartiel ·wildcardpartiel ·regexppartiel ·fuzzypartiel · les champs de métadonnées en clause (_id,_index, …)partiel ·constant_score·dis_max·function_scorepartiel ·boosting·termspartiel ·rangepartiel ·boolpartiel ·_name(nommer une clause),matched_queries,include_named_queries_score·query_stringpartiel ·simple_query_stringpartiel- recherche plein texte
lenient·type: best_fields(défaut) ·type: most_fields·type: phrase·type: phrase_prefix·operatorsousphrase/phrase_prefixpartiel- corps de recherche
POST|GET /{index}/_search,POST|GET /_search·query·from/size·sortpartiel ·_source·fieldspartiel ·docvalue_fieldspartiel ·stored_fields·highlightpartiel ·track_total_hitspartiel · Scoringpartiel · Format de réponse ·preferencepartiel ·aggs/aggregationspartiel ·scroll·min_score·search_after·POST /{index}/_pit,DELETE /_pit, et le blocpitdu corps ·timeout(paramètre et corps)partiel ·ignore_unavailable,allow_no_indices,expand_wildcards·GET|POST /{index}/_explain/{id},explain: truepartiel ·GET|POST /{index}/_field_capspartiel ·GET|POST /{index}/_validate/querypartiel- date math
now·now±<n><unité>·now/<unité>·<ancre>||<opérations>· date partielle (2026-03-15,2026-03,2026-03-15T12) ·formatsurrange· dansterm,terms,match, et sous unnested·time_zone- agrégations
min,max,sum,avg,value_count,stats·termspartiel ·rangepartiel ·histogrampartiel ·date_histogrampartiel · Sous-agrégations ·extended_statspartiel ·percentilespartiel ·top_hitspartiel ·filterpartiel- nested
{"nested": {"path", "query"}}· Clauses internespartiel ·score_modepartiel · Champs devinés sous unnested- join
{"type": "join", "relations": {...}}· Indexation ·has_child,has_parentpartiel ·parent_id·{"term": {"lien": "article"}}·routingpartiel
Un conteneur qu’on oublie.
L’image finale est un scratch qui contient un binaire lié statiquement — 1 couche contre 10. Rien d’autre : pas de libc, pas de shell, pas de JVM, rien à patcher un mardi.
coût mesuré
mesurée le 2 septembre 2026 · il y a 58 jours
vieille de plus d’un mois
Cette mesure date de 58 jours — au-delà des 30 jours après lesquels cette page cesse de la présenter comme l’état actuel. Le binaire grossit : entre les deux dernières campagnes du dépôt, l’image a bougé et le démarrage aussi, et c’est précisément pour cela que ce tableau est lu plutôt que tapé. Consultez la mesure pour savoir où on en est. Le dépôt signale que cette campagne a tourné sur un arbre modifié : l’image mesurée n’est donc peut-être pas celle que construit c2b4743 — Vrai si un des fichiers dont l'image est faite (src/, Cargo.toml, Cargo.lock, Dockerfile) differait de mesure.ferrite_sha pendant la campagne — donc si l'image mesuree pourrait ne pas etre celle que ce commit produit. Un README modifie au meme moment ne compte pas : il ne change pas un octet du binaire.
| Elasticsearch 8.15.0 | Spunto Search 0.11.0 | |
|---|---|---|
| image, telle qu’un registre la sert | 669,1 Mo | 4,3 Mo |
La somme des blobs qu'un registre sert pour cette image — le manifeste, la configuration et les couches telles qu'elles sont poussees. C'est ce qu'un | ||
| image, décompressée | 1,27 Go | 10,2 Mo |
La somme des couches une fois depliees, c'est-a-dire ce que le systeme de fichiers de l'image occupe une fois l'image tiree. | ||
| mémoire au repos | 1,08 Go | 4,9 Mo |
La somme des VmRSS de tous les processus du cgroup du conteneur, en kilo-octets, relevee 2 s apres le premier | ||
| docker run → première réponse | 18,1 s | 172 ms |
Le temps entre | ||
| ce que le conteneur exécute | /bin/tini | /ferrite — 10,2 Mo |
La taille du fichier que l'ENTRYPOINT du conteneur execute. | ||
Les deux colonnes sont mesurées par tests/compat/measure_container.sh sur la même machine, dans les mêmes conditions, contre un vrai Elasticsearch 8.15.0 tiré tel qu’Elastic le publie — jamais contre une idée de ce que coûte Elasticsearch. Les 172 ms sont l’aller-retour complet d’un docker run jusqu’à la première requête servie, et la médiane de 5 démarrages consécutifs : 263 ms · 170 ms · 174 ms · 169 ms · 172 ms. Pour ce binaire, l’essentiel de ce temps est Docker qui crée le conteneur.
- ce qui a été mesuré
ferrite:0.11.0, construite ici depuis le Dockerfile du dépôt àc2b4743, contredocker.elastic.co/elasticsearch/elasticsearch:8.15.0.- comment
./tests/compat/measure_container.sh --json docs/container.jsonsur linux/amd64, Docker 29.7.2 (overlayfs). La version du serveur Docker et son magasin d'images ne changent pas ce que cet outil mesure — il compte les octets de l'archive — mais ils changent ce que les AUTRES outils repondent a la meme question :docker image inspect --format '{{.Size}}'rendait la taille decompressee jusqu'a Docker 28 et rend la compressee depuis la 29, et la colonne DISK USAGE dedocker imagesen additionne encore une troisieme.- docker run
-p 9299:9200pour Spunto Search,-p 9299:9200 -e discovery.type=single-node -e xpack.security.enabled=false -e ES_JAVA_OPTS=-Xms512m -Xmx512mpour Elasticsearch — cela fait partie de la définition des lignes mémoire et démarrage, ce n’est pas un détail.- mesure brute
- docs/container.json — chaque chiffre ci-dessus, sa définition et le digest du manifeste des octets exacts comptés.
ce que ça change
Pas la requête — le déploiement. Un moteur de recherche qui démarre instantanément et tient en quelques mégaoctets cesse d’être un morceau d’infrastructure avec son propre plan de capacité et devient un détail : un sidecar à côté de l’app, un service dans un job de CI qui ne vaut pas la peine d’être mis en cache, un conteneur dans un environnement de dev déjà prêt avant que vous ayez changé de fenêtre.
C’est un seul nœud qui porte un seul shard sur un seul volume. Tout le compromis est là : pas de réplication, pas de bascule, pas de rééquilibrage — et rien de la machinerie qui leur donne le coût qu’ils ont.
services:
search:
build: https://github.com/spuntodotnet/search.git
ports:
- "9200:9200"
volumes:
- search-data:/data
volumes:
search-data:Aucune image n’est encore publiée : ceci construit depuis le dépôt — la même image scratch que mesure le tableau. Pas de Docker du tout ? Les releases fournissent un binaire musl statique pour x86-64 et arm64.
Rien n’échoue en silence.
Le mode d’échec qui compte dans une couche de compatibilité n’est pas une fonctionnalité manquante, c’est une fonctionnalité manquante qui répond 0 hits. Chaque clause, type de champ et route non implémentés renvoie une erreur au format d’Elasticsearch, avec un type — not_implemented_in_ferrite_exception — qui veut dire précisément « ES sait le faire, nous pas encore ».
Certains refus sont définitifs et voulus, et ce sont les plus intéressants : cardinality et slop sont refusés parce que Tantivy et Lucene ne s’accordent pas sur ce qu’ils doivent renvoyer, et les deux auraient été faciles à accepter et faux en silence. La raison de chaque refus est dans le dépôt, et elle est reproduite ci-dessous plutôt que résumée.
hors périmètre
Les 44 refus déclarés dans compat.yaml, par famille — les volontaires d’abord, « pas encore écrit » en dernier.
- hors périmètre, volontairement
- Cluster distribué —
_cluster/state,_cluster/stats,_cluster/reroute,_cluster/allocation/explain,_cluster/pending_tasks,_remote/info,_nodes/stats,_tasks· Snapshots, dépôts, restauration —_snapshot/*· Flux de données —_data_stream,data_streamdans un template · Tout ce qu'Elastic ajoute autour du moteur — sécurité et rôles (_security), machine learning (_ml), cycle de vie (_ilm,_slm),_watcher,_transform,_enrich,_eql,_sql,_esql,_inference, connecteurs, *search applications*,_rollup,_ccr,_graph, licence,_monitoring· Scripting —_scripts,_search/template,_render/template, Painless ·script_fields,runtime_mappings·routing,filter_path,typed_keys·search_type,max_concurrent_shard_requests,pre_filter_shard_size,batched_reduce_size - divergence de moteur
finnish· Noms de champ pointés (a.b) ou réservés ·type: cross_fields,bool_prefix·slop·histogram,date_histogram,rangesur un champ multivalué ·cardinality· Champtextdans une clause interne · Tri et agrégations sur un sous-champ denested, depuis la racine- refusé par Elasticsearch aussi
- L'API typée — un
{type}dans l'URL, un_typedans la réponse,include_type_name·fromavecscroll· Contexte expiré, fermé, ou jamais ouvert ·DELETE /{alias}· à l'indexation - pas encore écrit
- Les
_cat/*autres que_cat/indiceset_cat/health· Cycle de vie d'un index —_close,_open,_forcemerge,_shrink,_split,_clone,_rollover,_recovery,_segments,_flush,_upgrade,_cache/clear,_shard_stores,_resolve/index· Les autres routes de recherche —_search_shards,_termvectors,_mtermvectors,_suggest,_source·GET /{index}/_mapping/field/{champs}·_component_template,_simulate_index_template,_simulate·arabic,czech,greek,thaiet les autres langues ·char_filter· Un analyzer de type autre quecustom(french,standardparamétré…) · Tout autre type (geo_point,ip,binary…) · Autres paramètres de champ (null_value,doc_values,norms…) ·version/version_typeexternes ·_reindex, pipelines d'ingestion ·filter,routing,index_routing,search_routingsur un alias ·GET /_cat/aliases·remove_indexetaddd'un alias du même nom dans le mêmePOST /_aliases·GET /{index}/_aliassur un index fermé ·intervals,terms_set,script,span_*… ·collapse,knn,seq_no_primary_term,post_filter,suggest,rescore,track_scores,q,terminate_after,version,indices_boost,profile,slice,stats,ext,retriever·rest_total_hits_as_int·_msearch,_search/template·composite,filters,nested,significant_terms,date_range,ip_range,percentile_ranks,median_absolute_deviation… ·nesteddans unnested·inner_hits,ignore_unmapped
la raison de chaque refus — 44 entrées, dans les mots du dépôt
Cité mot pour mot depuis compat.yaml.
hors périmètre, volontairement
- Cluster distribué —
_cluster/state,_cluster/stats,_cluster/reroute,_cluster/allocation/explain,_cluster/pending_tasks,_remote/info,_nodes/stats,_tasks - ferrite est mono-nœud et mono-shard : il n'y a ni allocation, ni réallocation, ni tâche distribuée à rapporter, et une réponse plausible inventée pour ces routes serait un mensonge sur la nature du serveur.
- Snapshots, dépôts, restauration —
_snapshot/* - la sauvegarde d'un ferrite est la copie de son répertoire de données, ou l'export par
scroll; un dépôt de snapshots répliqué est de la mécanique de cluster. - Flux de données —
_data_stream,data_streamdans un template - un flux de données est une suite d'index gérée par
_rolloveret l'ILM, donc de l'exploitation de cluster posée au-dessus du moteur. Le refus est déclaré ici parce qu'il est exercé :helpers.reindexdu client officiel demandeGET /_data_stream/{cible}avant de copier, sur toute cible — c'est la suite serveur du client Python qui l'a montré, et sans cette ligne l'appel comptaitindeterminé, donc contre nous. - Tout ce qu'Elastic ajoute autour du moteur — sécurité et rôles (
_security), machine learning (_ml), cycle de vie (_ilm,_slm),_watcher,_transform,_enrich,_eql,_sql,_esql,_inference, connecteurs, *search applications*,_rollup,_ccr,_graph, licence,_monitoring - ce sont des produits posés sur le moteur, pas le moteur : chacun a son propre modèle de données et sa propre API, et aucun n'est ce qu'un client Elasticsearch existant appelle pour chercher des documents. C'est le corpus d'usage qui a montré qu'aucune capacité ne les réclamait — donc que 19 % de ses requêtes tombaient dans un trou de la déclaration, ni servies ni refusées.
- Scripting —
_scripts,_search/template,_render/template, Painless - un moteur de script est un langage à embarquer, à isoler et à maintenir : c'est exactement le genre de poids que ferrite existe pour ne pas porter.
script_fields,runtime_mappings- les deux définissent des champs calculés par un script Painless, que ferrite n'exécute pas. La mesure le confirme plutôt que la supposition : sur les 444 requêtes du corpus qui portent
runtime_mappings, 425 l'envoient vide (des gabarits de tracks Rally), et sur les 19 non vides 18 portent un script. L'objet vide est donc accepté — il ne définit aucun champ, donc ne demande rien, et ES rend la même réponse avec ou sans (mesuré) ; un objet non vide est refusé explicitement. routing,filter_path,typed_keys- ferrite est mono-shard,
routingn'a rien à choisir ; les deux autres changent la forme de la réponse, et une forme qui dépend d'un paramètre est une seconde API à mesurer. search_type,max_concurrent_shard_requests,pre_filter_shard_size,batched_reduce_size- ils reglent la façon dont une recherche se distribue entre shards ; il n'y en a qu'un, donc rien à distribuer et rien à régler.
divergence de moteur
finnish- le stemmer finnois de
rust-stemmerss'écarte de celui de Lucene sur 13 mots des 84 399 du vocabulaire finnois de Snowball (0,015 %) : il coupe la voyelle finale d'un emprunt à diacritique étranger là où l'algorithme la garde (garcíarendgarcíchez lui etgarcíachez ES ; de mêmebundesstraße,españa,musée). Un analyzer n'est jamais livré sous le nom d'ES tant qu'il n'est pas mesuré identique — un écart de 0,015 % rendu en 200 est le pire résultat possible ici. - Noms de champ pointés (
a.b) ou réservés - un point est le séparateur de chemin d'un objet : le porter dans un nom rendrait ambigu ce qu'un
client.villedésigne. Le préfixe_, lui, n'est pas réservé — seuls le sont les champs de métadonnées d'ES (_id,_source,_seq_no…) et les racines des colonnes internes de ferrite (_elem,_nelem,_join_parent), qu'un champ utilisateur écraserait. type: cross_fields,bool_prefix- le premier demande des statistiques de termes fusionnées entre champs, le second un scoring de suggestion : les approcher rendrait un autre classement que celui qu'un client attend.
slop- refusé quel que soit le type, pour la raison qui le fait refuser dans
match_phrase(divergence n° 2). histogram,date_histogram,rangesur un champ multivalué- l'agrégation de tantivy compte les valeurs, Elasticsearch compte les documents : un document dont le champ vaut
[1, 2, 3]tombe trois fois dans le bucket qui les contient (mesuré :doc_countde 4 là où ES en compte 2). Le refus n'est prononcé que si la colonne est réellement multivaluée — un champ à une valeur par document, le cas courant, reste servi et exact.terms,value_countetstatsne sont pas concernés : leurs comptes coïncident avec ceux d'ES. cardinality- l'estimation de tantivy diffère de celle d'ES (mesuré : 582 valeurs distinctes annoncées là où ES en compte 598), y compris sous le seuil où ES est exact — un compte approché sous le nom d'ES serait faux sans le dire.
- Champ
textdans une clause interne - les colonnes portent la valeur, pas les termes analysés : interroger son multi-field
.keyword, ou sortir la clause dunested. - Tri et agrégations sur un sous-champ de
nested, depuis la racine - ils porteraient sur les valeurs à plat, donc sur autre chose que ce que la requête a filtré. Chez Elasticsearch ces valeurs vivent dans des documents cachés : une agrégation n'en voit aucune et rend son résultat vide (
null,0.0,buckets: []), un tri est refusé (it is mandatory to set the [nested] context on the nested sort field). ferrite les porte sur le document parent : il rendait donc une moyenne de7.0là où ES rendnull, et un ordre en 200 là où ES rend 400. Un chiffre plausible et faux est le pire des résultats — le refus est explicite, et c'est le même que pour la requête équivalente (divergence n° 10).
refusé par Elasticsearch aussi
- L'API typée — un
{type}dans l'URL, un_typedans la réponse,include_type_name - elle a disparu en 8.x, la version que ferrite annonce : un vrai Elasticsearch 8 échoue au même endroit, et la rendre reviendrait à annoncer une version qu'on ne sert pas.
fromavecscroll- comme ES :
action_request_validation_exception. - Contexte expiré, fermé, ou jamais ouvert
- 404
search_phase_execution_exception, causesearch_context_missing_exception— la forme exacte d'ES, celle que les clients reconnaissent. DELETE /{alias}- effacer des index que le client n'a pas nommés n'est pas une suppression, c'est un accident ; ES 8 refuse de la même façon (« The provided expression [x] matches an alias, specify the corresponding concrete indices instead »).
- à l'indexation
{"d": "now"}est refusé, comme chez ES : le document porterait une date qui dépend de l'instant où il a été écrit.
pas encore écrit
- Les
_cat/*autres que_cat/indiceset_cat/health - ce sont des vues de texte sur un état que ferrite a pour la plupart ; elles ne sont pas écrites, et leurs tests exigent en plus les colonnes
h,sethelpque les deux_catexistants n'ont pas non plus. - Cycle de vie d'un index —
_close,_open,_forcemerge,_shrink,_split,_clone,_rollover,_recovery,_segments,_flush,_upgrade,_cache/clear,_shard_stores,_resolve/index - la moitié de ces routes n'a pas de sens sans shards (
_shrink,_split,_recovery,_shard_stores) ; l'autre moitié suppose un index qu'on peut arrêter de servir sans le supprimer (_close/_open), état que ferrite n'a pas. - Les autres routes de recherche —
_search_shards,_termvectors,_mtermvectors,_suggest,_source - aucune n'est demandée par le code client qu'on cherche à servir.
GET /{index}/_mapping/field/{champs}- route absente (
no handler found) : ferrite a pourtant le mapping, c'est un manque et pas une impossibilité — 15 cas de la suite d'Elastic tombent dessus. _component_template,_simulate_index_template,_simulate- un template de composants est un template qu'on cite depuis un autre : tant qu'il n'est pas lu,
composed_ofest refusé à la pose plutôt qu'appliqué à moitié. La simulation, elle, rend l'index qu'on obtiendrait — utile, et sans client qui la demande. arabic,czech,greek,thaiet les autres langues- leur chaîne demande des filtres de normalisation qui ne sont pas portés (et, pour plusieurs, un stemmer absent de
rust-stemmers). Rien n'y est mesuré : les douze langues servies le sont mot à mot, et celles-ci ne le seraient pas. char_filter- aucun mapping venu d'une instance réelle n'en a encore demandé ; c'est une brique à écrire, pas un obstacle.
- Un analyzer de type autre que
custom(french,standardparamétré…) - paramétrer un analyzer intégré (
stopwords,stem_exclusion) demande de reproduire sa composition interne exacte, qui n'est mesurée que dans sa forme par défaut. - Tout autre type (
geo_point,ip,binary…) - chacun demande son propre encodage et ses propres requêtes ; aucun n'est apparu dans les mappings des instances reprises jusqu'ici.
- Autres paramètres de champ (
null_value,doc_values,norms…) - les paramètres acceptés sont
type,analyzer,search_analyzer,fields,ignore_above,format,index,copy_toetstore; les autres sont refusés plutôt qu'acceptés sans effet, faute de quoi undoc_values: falselaisserait croire qu'un champ n'est pas triable. version/version_typeexternes- la version d'un document est gérée par ferrite ; l'imposer de l'extérieur demande de tenir un ordre que le serveur ne contrôle plus, et rien ne l'a encore réclamé.
_reindex, pipelines d'ingestion_reindexcopie d'un index vers un autre, et son intérêt est justement ce que ferrite n'a pas : une source distante, un pipeline, un script. Rien ne s'y oppose, ce n'est pas écrit — etscroll+_bulkle font aujourd'hui côté client, ce que ni_delete_by_queryni_update_by_queryne permettaient.filter,routing,index_routing,search_routingsur un alias- un alias filtré dont le filtre n'est pas appliqué rendrait précisément les documents qu'il est censé cacher ; le routage, lui, n'a rien à choisir sur un mono-shard.
GET /_cat/aliases- route absente (
no handler found) ; ses tests exigent en plush=,s=ethelpsur les_cat, que ferrite n'a pas — 10 cas de la suite d'Elastic tombent dessus. remove_indexetaddd'un alias du même nom dans le mêmePOST /_aliases- refusé en 400 (« an index or data stream exists with the same name as the alias ») : ferrite applique les alias avant les suppressions, là où ES calcule tout l'état puis l'applique — c'est pourtant l'usage même de
remove_index. GET /{index}/_aliassur un index fermé_close/_opensont hors périmètre, donc un index fermé n'existe pas ici.intervals,terms_set,script,span_*…parsing_exception: unknown query [...], avec la liste des clauses connues.collapse,knn,seq_no_primary_term,post_filter,suggest,rescore,track_scores,q,terminate_after,version,indices_boost,profile,slice,stats,ext,retriever- aucun n'est un obstacle de moteur.
search_afteretpit, qui manquaient le plus, sont servis depuis la carte 08. rest_total_hits_as_int- il change la forme de
hits.total(nombre au lieu d'objet) ; ES 8 l'accepte encore et du code venu de la 6.x/7.x s'en sert, voir [compat-es7.md](compat-es7.md). _msearch,_search/template_msearchest le plus regretté : un tableau de bord qui pose six facettes fait six appels au lieu d'un.composite,filters,nested,significant_terms,date_range,ip_range,percentile_ranks,median_absolute_deviation…filters(la sœur plurielle defilter) etcompositesont les deux qui manquent le plus ; aucune n'est un obstacle de moteur.nesteddans unnested- il faudrait un indice d'élément par niveau.
inner_hits,ignore_unmappedinner_hitsdemande de rendre l'élément qui a correspondu : ferrite le sait (c'est la colonne jumelle), il ne l'expose simplement pas.
à lire
C’est la version 0.10.0, un seul nœud, sans authentification. Quiconque atteint le port 9200 peut lire et écrire chaque index, et il n’y a de réplica nulle part — la durabilité de vos données est celle de ce seul volume. Traitez-le comme un index de recherche que vous pouvez reconstruire depuis votre source de vérité, sur un réseau privé, et il a exactement la bonne taille. Traitez-le comme une base de données et il vous décevra.
Le champ de recherche, pas le cluster de recherche.
La plupart des produits qui ont besoin de recherche ont besoin d’un index, de quelques centaines de milliers de documents et d’une facette ou deux — et finissent par faire tourner un système distribué conçu pour des pétaoctets, parce que c’est à lui que parle la bibliothèque cliente. Ceci parle à la même bibliothèque.
- sidecar
- dans le même fichier compose que l’app, sur le même volume, sans plan de capacité
- CI
- un conteneur de service qui démarre plus vite que l’étape de checkout qui le précède
- environnements de dev
- une sandbox Spunto qui arrive avec la recherche qui répond déjà
- en bordure d’un produit
- de la recherche dans une appliance, une installation sur site, un Raspberry Pi