Ir para o conteúdo
jsonbeautifiers
Português

Filtrar JSON

Extraia só o que você precisa com uma expressão de filtro JSONPath.

Documento
Resultado

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[?@.active]
Todo item em que a chave existe e é verdadeira. A existência sozinha já é um teste válido.
$.items[?@.price < 10]
Comparação numérica. A ordenação só vale entre dois números ou entre duas strings.
$.items[?@.type == 'book']
Comparação de strings. O literal precisa de aspas, e esse é o erro mais comum.
$.items[?@.price < 10 && @.stock > 0]
Conjunção com && e disjunção com ||, e agrupamento com parênteses.
$.items[?!@.archived]
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.
$..[?@.id == 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 !@.price 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?
$..[?@.aChave] aplica o filtro em qualquer profundidade. Para achar um registro específico, $..[?@.id == 42].