Filtrar JSON
Extraia só o que você precisa com uma expressão de filtro JSONPath.
Nada do que você cola sai do seu navegador. A lista de permissões connect-src transforma isso em uma garantia do navegador, e não em uma promessa. Confira você mesmo
Reduza um documento grande à parte de que você precisa, usando uma expressão de filtro JSONPath. O resultado volta como um array JSON com os valores que casaram, pronto para copiar.
Para deixar claro o que isto é: é JSONPath, não jq. O jq é uma linguagem completa e uma ferramenta genuinamente melhor para transformações complexas. Isto aqui é para selecionar, que é o que a maior parte das filtragens realmente é.
Expressões de filtro
A sintaxe inteira em um lugar só, já que é a parte que todo mundo consulta toda vez.
- $.items[[email protected]]
- Todo item em que a chave existe e é verdadeira. A existência sozinha já é um teste válido.
- $.items[[email protected] < 10]
- Comparação numérica. A ordenação só vale entre dois números ou entre duas strings.
- $.items[[email protected] == 'book']
- Comparação de strings. O literal precisa de aspas, e esse é o erro mais comum.
- $.items[[email protected] < 10 && @.stock > 0]
- Conjunção com && e disjunção com ||, e agrupamento com parênteses.
- $.items[[email protected]]
- Negação, que aqui significa que a chave está ausente ou é falsa.
- $.items[?length(@.tags) > 2]
- Uma extensão de função. length() funciona em strings, arrays e objetos.
- $.items[?match(@.sku, '[A-Z]{3}-[0-9]+')]
- Uma expressão regular ancorada ao valor inteiro. Use search() para casar com um trecho.
- $..[[email protected] == 42]
- Um filtro aplicado em qualquer profundidade, que é como você acha um registro sem saber onde ele mora.
O que acontece com uma chave ausente
É aqui que as implementações anteriores à RFC mais divergiam, então vale dizer. Na RFC 9535, uma consulta que não seleciona nada é "ausente", e um valor ausente só é igual a outro valor ausente. Então @.price < 10 é falso quando price não existe, em vez de lançar erro ou casar. Para uma comparação com == ser verdadeira, os dois lados precisam estar ausentes.
A consequência prática: para testar ausência use [email protected] em vez de @.price == null, porque null é um valor e ausência não é.
How to do this in code
Filtrando em código, onde o jq costuma ser a resposta certa.
sh jq
O terceiro exemplo é a linha que decide: se você precisa agrupar ou agregar, use 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); Perguntas frequentes
- Por que isto não é um playground de jq?
- Rodar jq de verdade no navegador significa entregá-lo compilado para WebAssembly, o que dá perto de um megabyte. Em um site cujo argumento é carregar rápido, é uma troca ruim para uma ferramenta que a maioria usa para selecionar e não para transformar. Além disso, chamar um filtro JSONPath de playground de jq seria mentira, e este site não faz isso.
- Dá para filtrar e remodelar ao mesmo tempo?
- Com JSONPath não: ele seleciona nós, não constrói novos. Use JMESPath, que tem multiselect hashes, ou jq.
- Como acho todos os objetos com uma certa chave em qualquer lugar do documento?
- $..[[email protected]] aplica o filtro em qualquer profundidade. Para achar um registro específico, $..[[email protected] == 42].