Skip to content
jsonforge.app
Retour au blog
Guide8 min de lecture

Travailler avec le JSON imbriqué : aplanir, interroger et transformer les données

Le JSON s'imbrique naturellement — des objets dans des objets, des tableaux dans des objets, des objets dans des tableaux — parce que c'est ainsi que les programmes modélisent les données. Les tableurs, fichiers CSV et tables SQL ne s'imbriquent pas du tout ; ils sont strictement bidimensionnels, lignes et colonnes. L'écart entre ces deux mondes est là qu'intervient l'« aplatissement », et savoir quand aplatir et quand laisser la structure tranquille, c'est l'essentiel de ce qui rend le JSON imbriqué gérable.

Pourquoi le JSON profondément imbriqué résiste aux tableurs et à SQL

Un objet JSON avec trois niveaux d'imbrication et un tableau enfoui quelque part n'a pas de correspondance ligne/colonne évidente — quel champ devient une colonne, et que faire d'un champ qui se répète par élément de tableau ? Coller du JSON imbriqué dans un convertisseur « JSON vers CSV » naïf ou l'import JSON d'Excel abandonne soit entièrement les champs imbriqués, soit les déverse dans une seule cellule sous forme de blob textuel — deux issues qui jettent exactement la structure sur laquelle vous voudriez filtrer, trier ou interroger.

Ce n'est pas tant un échec d'outillage qu'un véritable décalage de représentation : le JSON imbriqué encode un arbre, et un tableur ou une table SQL encode une liste plate d'enregistrements. Passer de l'un à l'autre exige une décision explicite sur la façon de gérer ce décalage, pas une simple conversion de format.

Ce que signifie réellement aplatir

Aplatir transforme une structure imbriquée en un objet à un seul niveau où chaque chemin imbriqué devient une clé, généralement jointe par un point (`user.address.city`) ou écrite en notation crochets (`user[address][city]`). Les éléments de tableau reçoivent un index dans le chemin (`roles.0`, `roles.1`), transformant une liste en un ensemble de clés adressables individuellement. Le résultat n'a plus aucune imbrication — chaque valeur est une simple chaîne, un nombre ou un booléen, et chaque clé identifie exactement une valeur feuille du document d'origine.

Cette propriété — une clé par valeur feuille, aucune imbrication — est exactement ce dont une colonne de tableur, une ligne SQL ou un simple magasin clé/valeur ont besoin.

Un exemple concret

Prenons un enregistrement utilisateur imbriqué typique avec un objet adresse et un tableau de chaînes de rôles.

Objet source imbriqué.
json
{
  "user": {
    "id": 42,
    "name": "Ada Lovelace",
    "address": {
      "city": "London",
      "postcode": "W1"
    },
    "roles": ["admin", "editor"]
  }
}
Les mêmes données aplaties en une carte clé/valeur à un niveau, avec chemins à points.
json
{
  "user.id": 42,
  "user.name": "Ada Lovelace",
  "user.address.city": "London",
  "user.address.postcode": "W1",
  "user.roles.0": "admin",
  "user.roles.1": "editor"
}

Six clés, zéro imbrication, et chacune est un chemin direct et sans ambiguïté vers une valeur d'origine — trivialement utilisables comme six colonnes de tableur ou six colonnes d'une seule ligne SQL.

Quand aplatir, quand conserver l'imbrication

Aplatissez quand la destination est réellement tabulaire — un export CSV, un tableur, une ligne d'une table SQL unique, un outil d'analyse qui ne comprend que les colonnes plates — et quand les tableaux sont de courtes listes de scalaires (comme `roles` ci-dessus) où une clé numérotée par index et par élément est un compromis raisonnable.

Conservez l'imbrication, ou restructurez plutôt que d'aplatir, quand un tableau contient des objets complets dont le nombre varie par enregistrement — un tableau `orders` où chaque utilisateur a un nombre différent de commandes, chacune avec plusieurs champs propres. Aplatir cela en place produit soit un ensemble de colonnes déchiquetées et différent par enregistrement (`orders.0.total`, `orders.1.total`, ... `orders.14.total` pour votre plus gros client), soit on renonce et l'on écrase tout le tableau en une cellule de JSON textuel, ce qui va contre tout l'intérêt de l'aplatissement. Le bon réflexe pour les tableaux d'objets est la normalisation relationnelle classique : extraire le tableau dans sa propre table/feuille avec une clé étrangère vers l'enregistrement parent, plutôt que d'essayer de le forcer en colonnes sur la ligne parente. C'est exactement ce que fait automatiquement l'outil JSON to Table de JsonForge — il aplatit les champs scalaires en colonnes et dégage les tableaux d'objets vers leurs propres tables liées au lieu de les défigurer en colonnes numérotées par index.

Accès par chemin : interroger sans tout aplatir

Parfois vous n'avez pas besoin d'aplatir un document entier — vous voulez juste une valeur dans une structure profondément imbriquée. La notation à points (`user.address.city`) ou une expression de type JSONPath (`$.user.address.city`, `$.roles[0]`) permet d'adresser directement une seule valeur imbriquée — la même idée sous-jacente que l'aplatissement, appliquée à une recherche au lieu du document entier. C'est ce qui alimente `lodash.get(obj, 'user.address.city')`, l'interpolation de variables de la plupart des moteurs de gabarits, et généralement les outils de requête JSON.

En pratique, les deux techniques se marient : l'outil JSON Flatten de JsonForge applique cette transformation à points sur un document entier d'un coup, transformant chaque valeur imbriquée en une clé plate et adressable — utile chaque fois que la destination est un tableur, un simple magasin clé/valeur, ou tout outil incapable de parcourir nativement les structures imbriquées.

FAQ

Quelle est la différence entre aplatir et simplement textualiser les champs imbriqués ?
Aplatir transforme chaque valeur imbriquée en sa propre clé scalaire de premier niveau, donc chaque valeur reste indépendamment interrogeable, triable et filtrable. Textualiser un champ imbriqué le réduit en un blob textuel opaque — vous pouvez l'afficher, mais vous ne pouvez ni filtrer sur une valeur interne, ni trier dessus sans réanalyser la chaîne au préalable. L'aplatissement préserve l'interrogeabilité ; la textualisation ne fait que repousser le problème.
Comment les tableaux sont-ils représentés quand on aplatit du JSON ?
La convention standard consiste à ajouter l'index du tableau au chemin, donc `roles: ["admin", "editor"]` devient `roles.0: "admin"` et `roles.1: "editor"`. Cela fonctionne proprement pour de courtes listes à peu près fixes de scalaires, mais produit un ensemble de clés déchiquetées et toujours croissantes pour les tableaux dont la longueur varie beaucoup entre enregistrements — dans ce cas, une table liée séparée est généralement plus adaptée que des clés d'index aplaties.
Un objet JSON aplati peut-il être reconverti en sa forme imbriquée d'origine ?
Oui — le « déplatissement » inverse le processus en redivisant chaque clé à points en ses composants et en reconstruisant les objets et tableaux imbriqués à partir d'eux, pour autant que la convention de séparateur ait été appliquée de façon cohérente et qu'aucune clé d'origine ne contenait littéralement un point.
La notation à points est-elle la seule façon de représenter une clé aplatie ?
Non. La notation à points (`user.address.city`) est la plus courante car elle reflète la façon dont vous accéderiez à la valeur en JavaScript ou Python, mais la notation crochets (`user[address][city]`) et les clés jointes par tirets bas (`user_address_city`) sont aussi utilisées, en particulier par les outils ciblant des environnements où les points dans les noms de colonnes posent problème (certains dialectes SQL, certains tableurs). La convention importe moins que de l'appliquer de façon cohérente à tout le document.

Essayez ces outils

Articles associés