JSONB — kompleks data strukturlarını, məsələn nested obyektləri və ya massivləri saxlamağa imkan verən güclü bir alətdir. Amma sadəcə JSONB-də məlumat saxlamaq kifayət deyil — biz bu datanı çıxarmağı da bacarmalıyıq. Məsələn, təsəvvür elə ki, users cədvəlində data adlı bir kolon var və orda bütün user ayarları JSONB formatında saxlanılır. İstəyirsən biləsən, user hansı tema seçib? Onu JSONB-obyektindən çıxarmalısan.
Əgər JSONB xəzinə sandığıdırsa, ->, ->>, #>> operatorları və jsonb_extract_path() kimi funksiyalar sənin açarındır. Gəlin baxaq, bunlardan necə istifadə etmək olar.
JSONB ilə işləmək üçün əsas operatorlar
PostgreSQL-də JSONB ilə işləmək üçün bir neçə əsas operator var. Onlar vasitəsilə açarlardan, nested obyektlərdən və massivlərdən dəyərləri çıxarmaq olur. Əsas operatorlar bunlardır:
-> operatoru
-> operatoru verilmiş açara görə obyekt və ya massiv çıxarır. Əgər dəyəri JSON formatında almaq istəyirsənsə, bu operator sənin üçündür.
Nümunə:
-- Data nümunəsi
SELECT '{"name": "Alice", "age": 25}'::jsonb -> 'name';
-- Nəticə: "Alice"
->> operatoru
->> operatoru -> kimi işləyir, amma çıxarılan dəyəri mətn kimi qaytarır. Bu, datanı sadə text kimi almaq istəyəndə faydalıdır.
Nümunə:
-- Data nümunəsi
SELECT '{"name": "Alice", "age": 25}'::jsonb ->> 'age';
-- Nəticə: "25" (sətir)
#>> operatoru
#>> operatoru nested obyektlərdən verilmiş path üzrə data çıxarır. Path açarların massiv kimi verilir.
Nümunə:
-- Data nümunəsi
SELECT '{"user": {"name": "Bob", "details": {"age": 30}}}'::jsonb #>> '{user, details, age}';
-- Nəticə: "30" (sətir)
-> və ->> fərqi:
Əgər data tipini (məsələn, massiv və ya obyekt) saxlamaq vacibdirsə, -> istifadə et. Sadəcə mətn lazımdırsa, ->> götür.
JSONB ilə işləmək üçün funksiyalardan istifadə
jsonb_extract_path() funksiyası JSONB-obyektindən verilmiş path üzrə dəyəri çıxarır. Bu, #>> operatorunun funksional analoqudur, amma bir az daha ifadəlidir.
Nümunə:
SELECT jsonb_extract_path('{"user": {"name": "Alice", "settings": {"theme": "dark"}}}'::jsonb, 'user', 'settings', 'theme');
-- Nəticə: "dark"
Əgər birbaşa mətn dəyəri almaq istəyirsənsə, jsonb_extract_path_text() istifadə et. Bu, jsonb_extract_path() kimi işləyir, amma sətir qaytarır.
Nümunə:
SELECT jsonb_extract_path_text('{"user": {"name": "Alice", "settings": {"theme": "dark"}}}'::jsonb, 'user', 'settings', 'theme');
-- Nəticə: dark
Praktik nümunələr
Açar üzrə dəyər çıxarmaq. Tutaq ki, products adlı cədvəlimiz var və details kolonunda JSONB formatında data saxlanılır:
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"}}');
Nəticə:
| 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"}} |
Bütün məhsulların brand-larını çıxaraq.
SELECT name, details->'brand' AS brand FROM products;
Nəticə:
| name | brand |
|---|---|
| Laptop | "Dell" |
| Phone | "Apple" |
Mətn dəyəri çıxarmaq. Əgər brand-ı dırnaqsız almaq istəyirik, ->> operatorundan istifadə edirik:
SELECT name, details->>'brand' AS brand FROM products;
Nəticə:
| name | brand |
|---|---|
| Laptop | Dell |
| Phone | Apple |
Nested datanı çıxarmaq. Hər məhsul üçün RAM həcmini (ram) çıxaraq:
SELECT name, details#>>'{specs, ram}' AS ram FROM products;
Nəticə:
| name | ram |
|---|---|
| Laptop | 16GB |
| Phone | 4GB |
Path üzrə data çıxarmaq. Eyni şeyi jsonb_extract_path_text() funksiyası ilə də etmək olar:
SELECT name, jsonb_extract_path_text(details, 'specs', 'ram') AS ram FROM products;
Nəticə:
| name | ram |
|---|---|
| Laptop | 16GB |
| Phone | 4GB |
Tipik səhvlər və onlardan necə qaçmaq olar
Səhvlər adətən bu hallarda olur:
- Yanlış path üzrə data çıxarmağa çalışırsan. Məsələn, əgər açar yoxdursa, nəticə
nullolacaq. - Tapşırığa uyğun olmayan operator istifadə edirsən.
->obyekt və massiv çıxarmaq üçündür, amma mətn üçün->>istifadə etmək lazımdır.
Səhv nümunəsi:
-- Səhv: 'nonexistent' açarı yoxdur
SELECT details->>'nonexistent' FROM products;
-- Nəticə: null
Məsləhət: Sorgu yazmazdan əvvəl data strukturunu həmişə yoxla ki, səhv olmasın.
Real tapşırıqlarda tətbiqi
JSONB-dən data çıxarmaq bir çox real tətbiqlərdə istifadə olunur:
- E-commerce-də məhsul xüsusiyyətləri ilə işləmək üçün.
- Web-app-lərdə user ayarlarını saxlamaq üçün.
- Analitikada event və log kimi strukturlaşdırılmış datanı işləmək üçün.
Bir nümunə də baxaq. Tutaq ki, orders adlı cədvəlimiz var və orda sifariş dataları saxlanılır:
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}]');
Bütün sifarişlərdən məhsul adlarını çıxaraq:
SELECT customer_name, jsonb_array_elements(items)->>'product' AS product FROM orders;
Nəticə:
| customer_name | product |
|---|---|
| John | Laptop |
| John | Mouse |
| Alice | Phone |
Davamda JSONB ilə daha dərin işləməyə, nested datanı araşdırmağa və onu analiz üçün daha rahat formata çevirməyə baxacağıq. Daha maraqlı şeylər üçün hazır ol!
GO TO FULL VERSION