Əgər JSONB — sehrli bir sandıqdırsa və biz ora dataları atırıqsa, || və jsonb_concat() — həmin sandıqları birləşdirməyə və ya içindəkiləri dəyişməyə imkan verən alətlərdir. Real həyatda sənə bir neçə JSON obyektini birləşdirmək, birindən digərinə data əlavə etmək və ya massivləri bir siyahıda toplamaq lazım ola bilər.
Məsələn, təsəvvür elə ki, səndə iki JSONB obyekti var:
{"ad": "Alice", "yas": 25}
və
{"seher": "Wonderland", "hobbilər": ["oxumaq", "shahmat"]}
Sən istəyirsən ki, nəticə belə olsun:
{"ad": "Alice", "yas": 25, "seher": "Wonderland", "hobbilər": ["oxumaq", "shahmat"]}
Və ya iki JSONB massivini birləşdir:
[1, 2, 3]
və
[4, 5, 6]
nəticə belə olsun:
[1, 2, 3, 4, 5, 6]
Bütün bunları || və ya jsonb_concat() ilə etmək olur. Gəlin baxaq necə işləyir.
JSONB birləşdirmək üçün || operatoru
|| operatoru PostgreSQL-də iki JSONB obyektini və ya massivini birləşdirməyə imkan verir. Sadə, sürətli və istifadəsi rahatdır. Əsas qaydaları bunlardır:
- Əgər iki JSONB obyekti birləşdirilirsə, nəticədə hər iki obyektin açarları və dəyərləri olacaq.
- Açarlar üst-üstə düşərsə, sağdakı operandın dəyəri soldakını əvəz edir.
- Əgər JSONB massivləri birləşdirilirsə, sol və sağ massivdəki elementlər bir massivdə toplanır.
Nümunə 1: İki JSONB obyektinin birləşdirilməsi
SELECT '{"ad": "Alice", "yas": 25}'::jsonb || '{"seher": "Wonderland", "hobbilər": ["oxumaq", "shahmat"]}'::jsonb AS birlesmis_obyekt;
Nəticə:
{"ad": "Alice", "yas": 25, "seher": "Wonderland", "hobbilər": ["oxumaq", "shahmat"]}
Nümunə 2: Açarlar üst-üstə düşəndə dəyərlərin yenilənməsi
SELECT '{"ad": "Alice", "yas": 25}'::jsonb || '{"yas": 30, "seher": "Wonderland"}'::jsonb AS yenilenmis_obyekt;
Nəticə:
{"ad": "Alice", "yas": 30, "seher": "Wonderland"}
Diqqət elə, "yas" açarının dəyəri sağ obyektin dəyəri ilə əvəz olundu.
Nümunə 3: Massivlərin birləşdirilməsi
SELECT '[1, 2, 3]'::jsonb || '[4, 5, 6]'::jsonb AS birlesmis_massiv;
Nəticə:
[1, 2, 3, 4, 5, 6]
JSONB birləşdirmək üçün jsonb_concat() funksiyası
jsonb_concat() funksiyası || operatoru kimi işləyir, amma daha çevikdir, xüsusən funksiyalarda, trigger-lərdə və ya dinamik sorğularda istifadə etmək lazım olanda. İki JSONB tipli arqument alır və birləşdirilmiş nəticə qaytarır.
Nümunə: jsonb_concat() istifadəsi
SELECT jsonb_concat('{"açar1": 1, "açar2": 2}'::jsonb, '{"açar2": 3, "açar3": 4}'::jsonb) AS birlesmis;
Nəticə:
{"açar1": 1, "açar2": 3, "açar3": 4}
Obyekt və massivlərin birləşdirilməsi: xüsusiyyətlər və incəliklər
Üst-üstə düşən açarlarla obyektləri birləşdirəndə sağ obyektin dəyərləri üstünlük təşkil edir.
Məsələn:
SELECT '{"açar1": "deyer1"}'::jsonb || '{"açar1": "deyer2"}'::jsonb AS netice;
Nəticə:
{"açar1": "deyer2"}
Əgər dəyərlərin əvəz olunmasını istəmirsənsə, belə dataları ayrı açarlarda saxla və ya başqa yanaşma seç (məsələn, massiv).
Massivlər isə həmişə sağ massivdəki elementləri sol massivə əlavə etməklə birləşir. Məsələn:
SELECT '["a", "b"]'::jsonb || '["c", "d"]'::jsonb AS netice;
Nəticə:
["a", "b", "c", "d"]
Əgər massivdə obyektlər varsa, obyektlərin sırası qorunur:
SELECT '[{"id": 1}, {"id": 2}]'::jsonb || '[{"id": 3}]'::jsonb AS netice;
Nəticə:
[{"id": 1}, {"id": 2}, {"id": 3}]
Praktik nümunələr
İstifadəçi profilinin yenilənməsi. Tutaq ki, səndə users adlı cədvəl var və profillər JSONB formatında saxlanılır:
CREATE TABLE users (
id SERIAL PRIMARY KEY,
profil JSONB
);
INSERT INTO users (profil) VALUES ('{"ad": "Alice", "yas": 25}');
İndi isə yaşadığı şəhəri əlavə etmək istəyirik:
UPDATE users
SET profil = profil || '{"seher": "Wonderland"}'
WHERE id = 1;
Sorğunun nəticəsi:
{"ad": "Alice", "yas": 25, "seher": "Wonderland"}
Sifariş məlumatlarının birləşdirilməsi. Tutaq ki, səndə orders adlı cədvəl var:
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
detallari JSONB
);
INSERT INTO orders (detallari) VALUES ('{"mehsullar": [{"mehsul": "laptop", "say": 1}]}');
İndi isə sifarişə daha bir məhsul əlavə edirik:
UPDATE orders
SET detallari = jsonb_set(
detallari,
'{mehsullar}',
detallari->'mehsullar' || '[{"mehsul": "mouse", "say": 2}]'::jsonb
)
WHERE id = 1;
Sorğunun nəticəsi:
{"mehsullar": [{"mehsul": "laptop", "say": 1}, {"mehsul": "mouse", "say": 2}]}
|| və jsonb_concat() arasındakı fərqlər
Funksional olaraq || operatoru və jsonb_concat() funksiyası eynidir. Sadə sorğular üçün || yazmaq daha rahatdır. jsonb_concat() isə proqram və ya trigger içində açıq şəkildə çağırmaq lazım olanda əlverişlidir.
Tipik səhvlər və onlardan yayınmaq yolları
Səhv: Uyğunsuz tipləri birləşdirməyə cəhd.
SELECT '{"açar": "deyer"}'::jsonb || '["deyer"]'::jsonb;
Nəticə:
ERROR: jsonb obyektləri və massivləri birləşdirmək olmur
Burada solda obyekt, sağda isə massiv var — PostgreSQL bunları birbaşa birləşdirə bilmir. Əməliyyat işləsin deyə, hər iki operand eyni tipdə olmalıdır: ya iki obyekt, ya da iki massiv.
Unudulan: JSONB ilə işləyəndə indekslərin olmaması
Əgər tez-tez JSONB sahələrindəki dəyərlərə görə filtr edirsənsə və indeks yoxdursa — sorğular çox ləngiyə bilər. Bu klassik səhv olmasa da, performans üçün ciddi problem yaradır. Mütləq GIN indekslərdən istifadə et:
CREATE INDEX idx_profil_data ON employees USING gin(profil);
GO TO FULL VERSION