JSONB — це потужний інструмент, який дозволяє зберігати складні структури даних, такі як вкладені об'єкти чи масиви. Але просто зберігати дані в JSONB замало — треба ще й уміти їх діставати. Наприклад, уяви, що в тебе є колонка data у таблиці users, де зберігаються всі користувацькі налаштування у форматі JSONB. Хочеш дізнатися, яку тему оформлення вибрав користувач? Доведеться витягти її з JSONB-об'єкта.
Якщо JSONB — це скриня зі скарбами, то оператори ->, ->>, #>> і функції, такі як jsonb_extract_path(), — це твої ключі. Давай розбиратися, як ними користуватись.
Основні оператори для роботи з JSONB
У PostgreSQL є кілька ключових операторів для роботи з JSONB. Вони дозволяють витягати значення з ключів, вкладених об'єктів і масивів. Ось основні з них:
Оператор ->
Оператор -> витягує об'єкт або масив за заданим ключем. Якщо хочеш отримати значення у тому ж форматі, що й у JSON, цей оператор — твій вибір.
Приклад:
-- Pryklad danykh
SELECT '{"name": "Alice", "age": 25}'::jsonb -> 'name';
-- Rezultat: "Alice"
Оператор ->>
Оператор ->> схожий на ->, але він повертає витягнуте значення у вигляді тексту. Це зручно, коли тобі треба отримати спрощене текстове представлення даних.
Приклад:
-- Pryklad danykh
SELECT '{"name": "Alice", "age": 25}'::jsonb ->> 'age';
-- Rezultat: "25" (stroka)
Оператор #>>
Оператор #>> витягує дані з вкладених об'єктів за вказаним шляхом. Шлях передається у вигляді масиву ключів.
Приклад:
-- Pryklad danykh
SELECT '{"user": {"name": "Bob", "details": {"age": 30}}}'::jsonb #>> '{user, details, age}';
-- Rezultat: "30" (stroka)
Різниця між -> та ->>:
Якщо важливо зберегти тип даних (наприклад, масив чи об'єкт), використовуй ->. Якщо потрібен текст — бери ->>.
Використання функцій для роботи з JSONB
Функція jsonb_extract_path() витягує значення з JSONB-об'єкта за вказаним шляхом. Це функціональний аналог оператора #>>, але трохи виразніший.
Приклад:
SELECT jsonb_extract_path('{"user": {"name": "Alice", "settings": {"theme": "dark"}}}'::jsonb, 'user', 'settings', 'theme');
-- Rezultat: "dark"
Якщо хочеш одразу отримати текстове значення, використовуй jsonb_extract_path_text(). Вона працює так само, як jsonb_extract_path(), але повертає строку.
Приклад:
SELECT jsonb_extract_path_text('{"user": {"name": "Alice", "settings": {"theme": "dark"}}}'::jsonb, 'user', 'settings', 'theme');
-- Rezultat: dark
Практичні приклади
Витяг значення за ключем. Припустимо, у нас є таблиця products, де в колонці details зберігаються дані у форматі 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"}}');
Результат:
| 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"}} |
Витягуємо бренди всіх продуктів.
SELECT name, details->'brand' AS brand FROM products;
Результат:
| name | brand |
|---|---|
| Laptop | "Dell" |
| Phone | "Apple" |
Витяг текстового значення. Якщо потрібен бренд без лапок, використовуємо оператор ->>:
SELECT name, details->>'brand' AS brand FROM products;
Результат:
| name | brand |
|---|---|
| Laptop | Dell |
| Phone | Apple |
Витяг вкладених даних. Витягуємо обсяг оперативної пам'яті (ram) для кожного продукту:
SELECT name, details#>>'{specs, ram}' AS ram FROM products;
Результат:
| name | ram |
|---|---|
| Laptop | 16GB |
| Phone | 4GB |
Витяг даних за шляхом. Те саме можна зробити з функцією jsonb_extract_path_text():
SELECT name, jsonb_extract_path_text(details, 'specs', 'ram') AS ram FROM products;
Результат:
| name | ram |
|---|---|
| Laptop | 16GB |
| Phone | 4GB |
Типові помилки та як їх уникнути
Помилки часто трапляються, коли ти:
- Пробуєш витягти дані за неправильним шляхом. Наприклад, якщо ключа не існує, результат буде
null. - Використовуєш неправильний оператор для задачі.
->підходить для витягу об'єктів і масивів, але для тексту треба застосовувати->>.
Приклад помилки:
-- Pomylka: kliucha 'nonexistent' nemaie
SELECT details->>'nonexistent' FROM products;
-- Rezultat: null
Порада: завжди перевіряй структуру даних перед написанням запитів, щоб уникнути помилок.
Застосування в реальних задачах
Витяг даних із JSONB використовується у багатьох реальних застосунках:
- У e-commerce для роботи з характеристиками товарів.
- У веб-додатках для зберігання користувацьких налаштувань.
- В аналітиці для обробки структурованих даних, таких як події та логи.
Ось ще один приклад. Припустимо, у нас є таблиця orders, де зберігаються дані про замовлення:
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}]');
Витягуємо назви всіх продуктів із замовлень:
SELECT customer_name, jsonb_array_elements(items)->>'product' AS product FROM orders;
Результат:
| customer_name | product |
|---|---|
| John | Laptop |
| John | Mouse |
| Alice | Phone |
Далі ми заглибимося у роботу з JSONB, досліджуючи вкладені дані та перетворення їх у більш зручний для аналізу вигляд. Готуйся до ще цікавіших відкриттів!
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ