CodeGym /Kurslar /SQL SELF /JSON-obyektlərdən məlumat çıxarmaq

JSON-obyektlərdən məlumat çıxarmaq

SQL SELF
Səviyyə , Dərs
Mövcuddur

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)

->->> 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ə null olacaq.
  • 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!

Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION