JSONB to potężne narzędzie, które pozwala przechowywać skomplikowane struktury danych, takie jak zagnieżdżone obiekty czy tablice. Ale samo trzymanie danych w JSONB to za mało — musimy umieć je wyciągać. Na przykład, wyobraź sobie, że masz kolumnę data w tabeli users, gdzie trzymane są wszystkie ustawienia użytkownika w formacie JSONB. Chcesz sprawdzić, jaki motyw wybrał użytkownik? Trzeba go wyciągnąć z JSONB-obiektu.
Jeśli JSONB to skrzynia ze skarbami, to operatory ->, ->>, #>> i funkcje, takie jak jsonb_extract_path(), to twoje klucze. Zobaczmy, jak z nich korzystać.
Podstawowe operatory do pracy z JSONB
W PostgreSQL mamy kilka kluczowych operatorów do pracy z JSONB. Pozwalają one wyciągać wartości z kluczy, zagnieżdżonych obiektów i tablic. Oto najważniejsze z nich:
Operator ->
Operator -> wyciąga obiekt lub tablicę po podanym kluczu. Jeśli chcesz dostać wartość w tym samym formacie co w JSON, to jest twój wybór.
Przykład:
-- Przykład danych
SELECT '{"name": "Alice", "age": 25}'::jsonb -> 'name';
-- Wynik: "Alice"
Operator ->>
Operator ->> jest podobny do ->, ale zwraca wyciągniętą wartość jako tekst. To przydatne, gdy chcesz dostać uproszczoną tekstową wersję danych.
Przykład:
-- Przykład danych
SELECT '{"name": "Alice", "age": 25}'::jsonb ->> 'age';
-- Wynik: "25" (string)
Operator #>>
Operator #>> wyciąga dane z zagnieżdżonych obiektów po podanej ścieżce. Ścieżka przekazywana jest jako tablica kluczy.
Przykład:
-- Przykład danych
SELECT '{"user": {"name": "Bob", "details": {"age": 30}}}'::jsonb #>> '{user, details, age}';
-- Wynik: "30" (string)
Różnica między -> i ->>:
Jeśli zależy ci na zachowaniu typu danych (np. tablica lub obiekt), użyj ->. Jeśli chcesz tekst, bierz ->>.
Użycie funkcji do pracy z JSONB
Funkcja jsonb_extract_path() wyciąga wartość z JSONB-obiektu po podanej ścieżce. To funkcjonalny odpowiednik operatora #>>, ale trochę bardziej czytelny.
Przykład:
SELECT jsonb_extract_path('{"user": {"name": "Alice", "settings": {"theme": "dark"}}}'::jsonb, 'user', 'settings', 'theme');
-- Wynik: "dark"
Jeśli chcesz od razu dostać wartość tekstową, użyj jsonb_extract_path_text(). Działa tak samo jak jsonb_extract_path(), ale zwraca stringa.
Przykład:
SELECT jsonb_extract_path_text('{"user": {"name": "Alice", "settings": {"theme": "dark"}}}'::jsonb, 'user', 'settings', 'theme');
-- Wynik: dark
Praktyczne przykłady
Wyciąganie wartości po kluczu. Załóżmy, że mamy tabelę products, gdzie w kolumnie details trzymane są dane w formacie 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"}}');
Wynik:
| 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"}} |
Wyciągamy marki wszystkich produktów.
SELECT name, details->'brand' AS brand FROM products;
Wynik:
| name | brand |
|---|---|
| Laptop | "Dell" |
| Phone | "Apple" |
Wyciąganie wartości tekstowej. Jeśli chcemy markę bez cudzysłowów, używamy operatora ->>:
SELECT name, details->>'brand' AS brand FROM products;
Wynik:
| name | brand |
|---|---|
| Laptop | Dell |
| Phone | Apple |
Wyciąganie zagnieżdżonych danych. Wyciągamy ilość RAM (ram) dla każdego produktu:
SELECT name, details#>>'{specs, ram}' AS ram FROM products;
Wynik:
| name | ram |
|---|---|
| Laptop | 16GB |
| Phone | 4GB |
Wyciąganie danych po ścieżce. To samo można zrobić funkcją jsonb_extract_path_text():
SELECT name, jsonb_extract_path_text(details, 'specs', 'ram') AS ram FROM products;
Wynik:
| name | ram |
|---|---|
| Laptop | 16GB |
| Phone | 4GB |
Typowe błędy i jak ich unikać
Błędy często pojawiają się, gdy:
- Próbujesz wyciągnąć dane po złej ścieżce. Na przykład, jeśli klucz nie istnieje, wynik będzie
null. - Używasz złego operatora do zadania.
->jest do wyciągania obiektów i tablic, ale do tekstu trzeba użyć->>.
Przykład błędu:
-- Błąd: klucza 'nonexistent' nie ma
SELECT details->>'nonexistent' FROM products;
-- Wynik: null
Tip: zawsze sprawdzaj strukturę danych przed pisaniem zapytań, żeby uniknąć błędów.
Zastosowanie w realnych zadaniach
Wyciąganie danych z JSONB jest używane w wielu prawdziwych aplikacjach:
- W e-commerce do pracy z cechami produktów.
- W aplikacjach webowych do trzymania ustawień użytkownika.
- W analizie do obróbki strukturalnych danych, takich jak eventy i logi.
Jeszcze jeden przykład. Załóżmy, że mamy tabelę orders, gdzie trzymane są dane o zamówieniach:
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}]');
Wyciągamy nazwy wszystkich produktów z zamówień:
SELECT customer_name, jsonb_array_elements(items)->>'product' AS product FROM orders;
Wynik:
| customer_name | product |
|---|---|
| John | Laptop |
| John | Mouse |
| Alice | Phone |
Dalej zagłębimy się w pracę z JSONB, eksplorując zagnieżdżone dane i przekształcanie ich w bardziej wygodny do analizy format. Szykuj się na jeszcze ciekawsze odkrycia!
GO TO FULL VERSION