JSONB é uma ferramenta poderosa que deixa a gente guardar estruturas de dados complexas, tipo objetos aninhados ou arrays. Mas só guardar os dados no JSONB não basta — a gente tem que saber como tirar esses dados de lá. Por exemplo, imagina que tu tem uma coluna data na tabela users, onde ficam todas as configurações do usuário em formato JSONB. Quer saber qual tema o usuário escolheu? Vai ter que extrair isso do objeto JSONB.
Se JSONB é um baú de tesouros, então os operadores ->, ->>, #>> e funções tipo jsonb_extract_path() são as tuas chaves. Bora ver como usar cada uma delas.
Principais operadores pra trabalhar com JSONB
No PostgreSQL tem vários operadores chave pra mexer com JSONB. Eles deixam a gente extrair valores de chaves, objetos aninhados e arrays. Olha só os principais:
Operador ->
O operador -> extrai um objeto ou array pela chave que tu passar. Se tu quer pegar o valor no mesmo formato do JSON, esse operador é o que tu precisa.
Exemplo:
-- Exemplo de dados
SELECT '{"name": "Alice", "age": 25}'::jsonb -> 'name';
-- Resultado: "Alice"
Operador ->>
O operador ->> é parecido com o ->, mas ele devolve o valor extraído como texto. Isso é útil quando tu quer só o texto puro dos dados.
Exemplo:
-- Exemplo de dados
SELECT '{"name": "Alice", "age": 25}'::jsonb ->> 'age';
-- Resultado: "25" (string)
Operador #>>
O operador #>> tira dados de objetos aninhados pelo caminho que tu passar. O caminho é passado como um array de chaves.
Exemplo:
-- Exemplo de dados
SELECT '{"user": {"name": "Bob", "details": {"age": 30}}}'::jsonb #>> '{user, details, age}';
-- Resultado: "30" (string)
Diferença entre -> e ->>:
Se tu precisa manter o tipo do dado (tipo array ou objeto), usa ->. Se tu quer só o texto, vai de ->>.
Usando funções pra trabalhar com JSONB
A função jsonb_extract_path() extrai um valor de um objeto JSONB pelo caminho que tu passar. É tipo um jeito funcional de fazer o que o operador #>> faz, mas fica mais expressivo.
Exemplo:
SELECT jsonb_extract_path('{"user": {"name": "Alice", "settings": {"theme": "dark"}}}'::jsonb, 'user', 'settings', 'theme');
-- Resultado: "dark"
Se tu já quer pegar o valor como texto, usa jsonb_extract_path_text(). Ela funciona igual a jsonb_extract_path(), mas devolve uma string.
Exemplo:
SELECT jsonb_extract_path_text('{"user": {"name": "Alice", "settings": {"theme": "dark"}}}'::jsonb, 'user', 'settings', 'theme');
-- Resultado: dark
Exemplos práticos
Extraindo valor por chave. Imagina que a gente tem uma tabela products, onde a coluna details guarda dados em formato JSONB:
CREATE TABLE products (
id SERIAL PRIMARY KEY,
name TEXT,
details JSONB
);
INSERT INTO products (name, details) VALUES
('Laptop', '{"brand": "Dell", "price": 1200, "specs": {"ram": "16GB", "cpu": "Intel i7"}}'),
('Phone', '{"brand": "Apple", "price": 1000, "specs": {"ram": "4GB", "cpu": "A13"}}');
Resultado:
| id | name | details |
|---|---|---|
| 1 | Laptop | {"brand": "Dell", "price": 1200, "specs": {"ram": "16GB", "cpu": "Intel i7"}} |
| 2 | Phone | {"brand": "Apple", "price": 1000, "specs": {"ram": "4GB", "cpu": "A13"}} |
Vamos extrair as marcas de todos os produtos.
SELECT name, details->'brand' AS brand FROM products;
Resultado:
| name | brand |
|---|---|
| Laptop | "Dell" |
| Phone | "Apple" |
Extraindo valor como texto. Se a gente quer a marca sem aspas, usa o operador ->>:
SELECT name, details->>'brand' AS brand FROM products;
Resultado:
| name | brand |
|---|---|
| Laptop | Dell |
| Phone | Apple |
Extraindo dados aninhados. Vamos pegar a quantidade de RAM (ram) de cada produto:
SELECT name, details#>>'{specs, ram}' AS ram FROM products;
Resultado:
| name | ram |
|---|---|
| Laptop | 16GB |
| Phone | 4GB |
Extraindo dados por caminho. Dá pra fazer a mesma coisa usando a função jsonb_extract_path_text():
SELECT name, jsonb_extract_path_text(details, 'specs', 'ram') AS ram FROM products;
Resultado:
| name | ram |
|---|---|
| Laptop | 16GB |
| Phone | 4GB |
Erros comuns e como evitar
Os erros aparecem bastante quando tu:
- Tenta extrair dados por um caminho errado. Por exemplo, se a chave não existe, o resultado vai ser
null. - Usa o operador errado pra tarefa.
->serve pra extrair objetos e arrays, mas pra texto tem que usar->>.
Exemplo de erro:
-- Erro: a chave 'nonexistent' não existe
SELECT details->>'nonexistent' FROM products;
-- Resultado: null
Dica: sempre confere a estrutura dos dados antes de escrever as queries, pra não dar ruim.
Usando na vida real
Extrair dados do JSONB rola em vários apps de verdade:
- No e-commerce pra lidar com características dos produtos.
- Em apps web pra guardar configurações dos usuários.
- Na análise de dados pra processar dados estruturados, tipo eventos e logs.
Olha mais um exemplo. Imagina que a gente tem uma tabela orders, onde ficam os dados dos pedidos:
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
customer_name TEXT,
items JSONB
);
INSERT INTO orders (customer_name, items) VALUES
('John', '[{"product": "Laptop", "quantity": 1}, {"product": "Mouse", "quantity": 2}]'),
('Alice', '[{"product": "Phone", "quantity": 1}]');
Vamos extrair os nomes de todos os produtos dos pedidos:
SELECT customer_name, jsonb_array_elements(items)->>'product' AS product FROM orders;
Resultado:
| customer_name | product |
|---|---|
| John | Laptop |
| John | Mouse |
| Alice | Phone |
Depois a gente vai se aprofundar mais no JSONB, explorando dados aninhados e transformando eles pra um formato mais fácil de analisar. Fica ligado que vem coisa ainda mais massa por aí!
GO TO FULL VERSION