Passer des API avec type aux API sans type dans Elasticsearch 7.0 | Elastic Blog
Technique

Oubliez les types, l'avenir est au sans type.

Depuis la version 5.0, nous avons ouvert la voie au retrait des types sur Elasticsearch. La version 7.0 marque leur fin. Le but des types était d'assurer une architecture multi-tenant au sein d'un seul index, ce qui est incompatible avec Lucene. Malheureusement, les types se sont révélés plus problématiques que salutaires. Après avoir longuement débattu afin de savoir si nous devions contourner le problème (ex. : utiliser des champs uniques par type ou disposer d'un index par type), nous avons décidé de supprimer la prise en charge des types. Pour assurer une transition en douceur à nos utilisateurs, nous avons réparti les changements sur quatre versions majeures :

  • la version 5.0 a commencé à imposer que les champs partageant le même nom sur plusieurs types aient des mappings compatibles ;
  • la version 6.0 a commencé à empêcher les nouveaux index de disposer de plus d'un type et n’accepte plus le mapping _default_ ;
  • la version 7.0 a rejeté les API qui acceptent les types, créé de nouvelles API sans type et supprimé la prise en charge du mapping _default_ ;
  • la version 8.0 supprimera toutes les API qui acceptent les types.

API sans type

Toutes les API qui acceptent les types dans leur chemin URL, leur corps de requête ou leur corps de réponse obtiennent un nouvel équivalent "sans type". C'est le cas de certaines API très courantes telles que les API GET, de création d'index et d'index. Un exemple valant toujours mieux qu'un long discours, voici à quoi ressemble une interaction avec un cluster 7.0 avec des API sans type :

PUT index
{
  "mappings": {
    "properties": { // Note how there is no top-level key with the type name
      "@timestamp": {
        "type": "date"
      }
    }
  }
}
PUT index/_doc/1 // _doc becomes the new endpoint for document index, get and delete requests
{
  "@timestamp": "2019-02-20"
}
POST index/_bulk
{"index": {"_id": "2"}} // no _type in the URL or in document metadata
{"@timestamp": "2019-03-01"}
{"update": {"_id": "1"}}
{"@timestamp": "2019-02-21"}
GET index/_doc/2
GET index/_search // unchanged, the `GET index/{type}/_search` endpoint is deprecated however
{
  "query": {
    "range": {
      "@timestamp": {
        "gte": "2019-01-01"
      }
    }
  }
}
GET index/_explain/1 // note how the type does not appear in the URL anymore, this would have been "GET index/{type}/1/_explain" in 6.x
{
  "query": {
    "range": {
      "@timestamp": {
        "gte": "2019-01-01"
      }
    }
  }
}

Que dois-je faire ?

Certains changements sont majeurs et vous obligent à procéder à des modifications sur votre cluster avant de passer à la version 7.0. D'autres ne seront requis que pour la mise à niveau vers la version 8.0 et ne doivent être effectués qu'après la mise à niveau vers la version 7.0.

Avant la mise à niveau

Assurez-vous d'être à la version 6.8

Si vous prévoyez d'effectuer une mise à niveau propagée sans aucune indisponibilité, vous devez d'abord passer à la version 6.8. En effet, c'est la seule version 6.x à disposer de fonctionnalités telles que la prise en charge du paramètre include_type_name qui permet de passer à la version 7.0 sans encombre.

Arrêtez d'utiliser les mappings _default_

Le mapping _default_ n'est plus pris en charge par la version 7.0. Si certains index 6.x existants disposent d'un mapping _default_, ce n'est pas grave, car le mapping _default_ ne sera rejeté que sur les nouveaux index.

Vous devez mettre à jour vos modèles d'index ainsi que votre code d'application pour ajouter ces mappings au type réel, plutôt que de les inclure à un mapping _default_. Bien que le nom du type ne soit pas important, nous vous recommandons d'utiliser _doc. Cela permettra de faciliter la transition vers les API sans type.

Passez le paramètre include_type_name=true aux API de mapping, de modèle et de création d'index

Le passage aux API sans type implique que les API dont les corps de requête nécessitaient un type vont à présent exiger un format différent :

  • create index
  • put mapping
  • put template

tandis que d'autres API ayant retourné des types dans la réponse vont avoir un format de réponse différent :

  • get index
  • get mapping
  • get field mapping
  • get template

Afin de ne pas être perturbé par ce changement, vous devriez faire en sorte que votre application passe le paramètre include_type_name=true à ces appels d'API, qui est une instruction nulle sur la version 6.x. La version 7.x indiquera ainsi à ces API de se comporter comme elles le faisaient dans la version 6.x. Par exemple, voici un appel de création d'index avec ce paramètre. Il fonctionne de la même façon sur 6.8 et 7.x.

PUT index?include_type_name=true
{
  "mappings": {
    "my_type": {
      "properties": { // Note how there is no top-level key with the type name
        "@timestamp": {
          "type": "date"
        }
      }
    }
  }
}

Après la mise à niveau

Si vous avez suivi les étapes préalables à la mise à niveau qui vous ont été recommandées, tout devrait fonctionner normalement. Toutefois, pour le moment, vous continuez d'utiliser des API qui acceptent des types, et donc de recevoir des avertissements de désapprobation. Pour vous en débarrasser, vous devez migrer vers les API sans type.

Pour les API de mapping, de modèle et de création d'index, vous devrez retirer include_type_name=true des paramètres d'URL et modifier les corps de requêtes ou les attentes concernant le format de réponse, qui n'inclut plus les types. Si le corps de requête ou de réponse incluait des mappings, il affichait probablement une section semblable à celle-ci :

{
  "my_type": { // this key is no longer accepted in mappings as of 7.0
    "properties": ...
  }
}

Il doit être mis à niveau pour ne plus inclure de nom de type et devrait à présent ressembler à cela :

{
  "properties": ...
}

Pour les autres API (Index, GET ou Update, par exemple), vous devez remplacer le nom de type dans l'URL par _doc. Cela fonctionnera, quel que soit le nom du type de votre index. Par exemple, si vous aviez l'habitude d'effectuer des appels d'index pour un index dont le nom de type est my_type, l'appel d'index ressemblait à cela :

PUT index/my_type/1
{
  "@timestamp": "2019-02-20"
}

et doit être remplacé par :

PUT index/_doc/1
{
  "@timestamp": "2019-02-20"
}

En savoir plus

Si vous souhaitez en savoir plus sur le retrait des types et la migration vers des API sans type, je vous recommande de jeter un œil à notre documentation sur la suppression des types. Vous y trouverez des informations détaillées concernant les répercussions de cette évolution, ainsi que des conseils pour vous y préparer.

Téléchargez la version 7.0.0, donnez une chance à ces nouvelles API sans type et dites-nous ce que vous en pensez sur le forum.