Filtrer du JSON
Extrayez uniquement ce dont vous avez besoin avec une expression de filtre JSONPath.
Rien de ce que vous collez ne quitte votre navigateur. La liste d’autorisation connect-src en fait une garantie du navigateur plutôt qu’une promesse. Vérifiez-le vous-même
Réduisez un gros document à la partie dont vous avez besoin, à l’aide d’une expression de filtre JSONPath. Le résultat revient sous forme de tableau JSON des valeurs correspondantes, prêt à copier.
Pour être clair sur ce que c’est : c’est du JSONPath, pas du jq. jq est un langage complet et un outil véritablement supérieur pour les transformations complexes. Ceci sert à sélectionner, ce que la plupart des filtrages sont en réalité.
Expressions de filtre
Toute la syntaxe au même endroit, puisque c’est la partie que l’on recherche à chaque fois.
- $.items[[email protected]]
- Chaque élément dont la clé existe et est vraie. La seule existence est déjà un test valide.
- $.items[[email protected] < 10]
- Comparaison numérique. L’ordre ne s’applique qu’entre deux nombres ou entre deux chaînes.
- $.items[[email protected] == 'book']
- Comparaison de chaînes. Le littéral doit être entre guillemets, et c’est l’erreur la plus courante.
- $.items[[email protected] < 10 && @.stock > 0]
- Conjonction avec && et disjonction avec ||, et regroupement avec des parenthèses.
- $.items[[email protected]]
- Négation, qui signifie ici que la clé est absente ou fausse.
- $.items[?length(@.tags) > 2]
- Une extension de fonction. length() fonctionne sur les chaînes, les tableaux et les objets.
- $.items[?match(@.sku, '[A-Z]{3}-[0-9]+')]
- Une expression régulière ancrée à la valeur entière. Utilisez search() pour une correspondance partielle.
- $..[[email protected] == 42]
- Un filtre appliqué à toutes les profondeurs, ce qui permet de trouver un enregistrement sans savoir où il se trouve.
Ce qu’il advient d’une clé absente
C’est le point sur lequel les implémentations pré-RFC divergeaient le plus, il vaut donc la peine de l’énoncer. Dans la RFC 9535, une requête qui ne sélectionne rien est « manquante », et une valeur manquante n’est égale qu’à une autre valeur manquante. Donc @.price < 10 est faux quand price est absent, plutôt que de lever une erreur ou de correspondre. Les deux membres d’une comparaison == doivent être manquants pour qu’elle soit vraie.
Conséquence pratique : pour tester l’absence, utilisez [email protected] plutôt que @.price == null, car null est une valeur et l’absence n’en est pas une.
How to do this in code
Filtrer en code, là où jq est généralement la bonne réponse.
sh jq
Le troisième exemple est celui qui tranche : si vous avez besoin de regrouper ou d’agréger, prenez jq.
# Select, then reshape
jq '[.items[] | select(.price < 10) | {sku, price}]' data.json
# Filter at any depth
jq '[.. | objects | select(.id? == 42)]' data.json
# Group and aggregate, which JSONPath cannot do at all
jq 'group_by(.category) | map({category: .[0].category, n: length})' data.json py Python
# A comprehension beats a query language for anything you
# can express directly.
cheap = [i for i in data['items'] if i['price'] < 10]
# JMESPath when the filter is configuration rather than code
import jmespath
cheap = jmespath.search("items[?price < `10`]", data) js JavaScript
const cheap = data.items.filter((i) => i.price < 10);
// Deep search without a library
function findAll(node, test, out = []) {
if (node && typeof node === 'object') {
if (test(node)) out.push(node);
for (const v of Object.values(node)) findAll(v, test, out);
}
return out;
}
const matches = findAll(data, (n) => n.id === 42); Questions fréquentes
- Pourquoi n’est-ce pas un bac à sable jq ?
- Faire tourner du vrai jq dans un navigateur suppose de l’expédier compilé en WebAssembly, soit environ un mégaoctet. Sur un site dont l’argument est qu’il charge vite, c’est un mauvais échange pour un outil que la plupart des gens utilisent pour sélectionner et non pour transformer. Et appeler « bac à sable jq » un filtre JSONPath serait un mensonge, ce que ce site ne fait pas.
- Puis-je filtrer et remodeler en même temps ?
- Pas avec JSONPath : il sélectionne des nœuds, il n’en construit pas de nouveaux. Utilisez JMESPath, qui dispose des multiselect hashes, ou jq.
- Comment trouver tous les objets ayant une clé donnée n’importe où dans le document ?
- $..[[email protected]é] applique le filtre à toutes les profondeurs. Pour trouver un enregistrement précis, $..[[email protected] == 42].