Membuat Pertanyaan JSONB dengan JSONPath
Gunakan ungkapan laluan SQL/JSON untuk menapis dan mengekstrak nilai bersarang dengan sokongan indeks.
Membuat Pertanyaan JSONB dengan JSONPath ialah pelajaran Prestasi PostgreSQL & Pengoptimuman Pertanyaan percuma di CoddyKit. Ini ialah pelajaran 3 daripada 4. Sebanyak 3 pelajaran dalam laluan pembelajaran ini boleh dibaca sepenuhnya secara percuma — selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan praktikal dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Prestasi PostgreSQL & Pengoptimuman Pertanyaan, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Prestasi PostgreSQL & Pengoptimuman Pertanyaan merangkumi sejumlah 4 pelajaran.
Mengapa JSONPath untuk JSONB
PostgreSQL menyimpan data separa berstruktur dalam jenis jsonb. Mendapatkan nilai bersarang dengan operator klasik -> dan ->> boleh dilakukan, tetapi cepat menjadi rumit untuk laluan yang dalam, tatasusunan dan penapis bersyarat.
Bahasa laluan SQL/JSON (ditambahkan dalam PostgreSQL 12) memberikan cara yang ringkas dan berkuasa untuk menavigasi serta menapis JSON. Bahasa ini menggerakkan dua fungsi utama:
jsonb_path_query/jsonb_path_query_array— mengekstrak nilai yang sepadanjsonb_path_existsdan operator@?/@@— menguji predikat
Lebih baik lagi, operator tersebut boleh dipercepatkan oleh indeks GIN, dan itulah tepatnya perkara yang dibincangkan dalam pelajaran ini.
Contoh Dokumen JSONB
Bayangkan jadual orders dengan lajur data jsonb. Satu baris mungkin mengandungi dokumen seperti di bawah.
Sepanjang pelajaran ini, kita akan menavigasi ke dalam customer, mengulangi setiap elemen dalam tatasusunan items, serta menapis berdasarkan syarat angka dan rentetan.
SELECT '{
"id": 1042,
"status": "shipped",
"customer": { "name": "Mara", "tier": "gold" },
"items": [
{ "sku": "A-1", "qty": 2, "price": 19.90 },
{ "sku": "B-7", "qty": 1, "price": 4.50 }
]
}'::jsonb AS data;Akar $ dan Navigasi Bertitik
Setiap ungkapan JSONPath bermula pada $, iaitu item konteks (keseluruhan dokumen). Dari situ, anda menggunakan tatatanda titik untuk kunci objek.
$.status→ nilai kuncistatus$.customer.name→ nilai bersarang
jsonb_path_query mengembalikan setiap padanan sebagai nilai jsonb. Perhatikan bahawa hasil rentetan mengekalkan tanda petik; gunakan jsonb_path_query_first(...) #>> '{}' atau penukaran jenis jika anda memerlukan teks biasa.
SELECT jsonb_path_query(
'{"status":"shipped","customer":{"name":"Mara"}}'::jsonb,
'$.customer.name'
) AS name;Menavigasi ke Dalam Tatasusunan
Untuk mencapai elemen tatasusunan, gunakan kurungan siku. Indeks bermula dari sifar.
$.items[0]→ elemen pertama$.items[*]→ kad bebas, setiap elemen$.items[*].sku→skubagi setiap elemen
Apabila laluan sepadan dengan banyak nilai, jsonb_path_query mengembalikan satu baris bagi setiap padanan. Balut panggilan tersebut dalam jsonb_path_query_array untuk mengumpulkannya ke dalam satu tatasusunan JSON.
SELECT jsonb_path_query_array(
'{"items":[{"sku":"A-1"},{"sku":"B-7"}]}'::jsonb,
'$.items[*].sku'
) AS skus;Menapis Ungkapan dengan ? ( )
Kekuatan sebenar JSONPath ialah ungkapan penapis: ? ( predicate ). Dalam penapis, @ merujuk kepada item semasa yang sedang diuji.
Untuk mendapatkan setiap item yang kuantitinya sekurang-kurangnya 2:
$.items[*] ? (@.qty >= 2)
Penapis hanya mengekalkan elemen tatasusunan yang memenuhi predikat. Anda kemudiannya boleh terus menavigasi, contohnya $.items[*] ? (@.qty >= 2).sku untuk mengembalikan SKU sahaja.
SELECT jsonb_path_query(
'{"items":[{"sku":"A-1","qty":2},{"sku":"B-7","qty":1}]}'::jsonb,
'$.items[*] ? (@.qty >= 2).sku'
) AS heavy_skus;Menggabungkan Predikat dan Operator
Predikat penapis menyokong operator perbandingan biasa (==, !=, <, <=, >, >=) serta penghubung boolean && dan ||.
Perhatikan bahawa operator kesamaan dalam JSONPath ialah ==, bukannya = tunggal SQL. Rentetan ditulis dengan tanda petik berganda.
$.items[*] ? (@.qty > 1 && @.price < 10)$ ? (@.customer.tier == "gold")
Kurungan membolehkan anda mengumpulkan logik kompleks sama seperti dalam SQL.
SELECT jsonb_path_query(
'{"items":[{"sku":"A-1","qty":2,"price":19.9},{"sku":"C-9","qty":3,"price":4.5}]}'::jsonb,
'$.items[*] ? (@.qty > 1 && @.price < 10)'
) AS cheap_bulk;Menguji Kewujudan: @? dan @@
Untuk menapis baris dalam klausa WHERE, biasanya anda memerlukan boolean, bukan nilai yang sepadan. Dua operator melakukan perkara ini:
jsonb @? jsonpath→ benar jika laluan mengembalikan sebarang itemjsonb @@ jsonpath→ menilai laluan yang sendiri menghasilkan predikat boolean
Peraturan mudah: dengan @?, penapis berada di dalam laluan ($.items[*] ? (@.qty > 5)); dengan @@, laluan itu ialah predikat ($.customer.tier == "gold"). Kedua-duanya boleh diindeks oleh GIN.
SELECT
data @? '$.items[*] ? (@.qty > 5)' AS has_bulk_item,
data @@ '$.customer.tier == "gold"' AS is_gold
FROM (SELECT '{"customer":{"tier":"gold"},"items":[{"qty":2}]}'::jsonb AS data) t;Menapis Baris dalam Pertanyaan Sebenar
Inilah corak yang paling kerap anda tulis: pilih baris yang dokumen JSONB-nya memenuhi predikat laluan. Oleh sebab @? boleh diindeks, pertanyaan ini boleh dijalankan tanpa imbasan berjujukan setelah indeks yang betul tersedia.
Pertanyaan ini mencari pesanan yang telah dihantar dan mengandungi sekurang-kurangnya satu item berharga lebih daripada 100.
SELECT id, data->>'status' AS status
FROM orders
WHERE data @? '$.items[*] ? (@.price > 100)'
AND data @@ '$.status == "shipped"';Mengindeks dengan GIN jsonb_ops Lalai
Indeks GIN biasa pada lajur menggunakan kelas operator jsonb_ops. Indeks ini mengindeks setiap kunci dan setiap nilai, serta menyokong containment (@>), kewujudan kunci (?), dan operator laluan JSON @? / @@.
Indeks ini fleksibel tetapi lebih besar kerana setiap nilai mendapat entri indeksnya sendiri.
CREATE INDEX idx_orders_data ON orders USING gin (data);
-- Now this predicate can use the index:
EXPLAIN ANALYZE
SELECT id FROM orders
WHERE data @? '$.items[*] ? (@.price > 100)';Lebih Kecil dan Pantas: jsonb_path_ops
Jika anda hanya memerlukan containment dan carian laluan JSON (bukan operator kewujudan kunci kendiri ?), kelas operator jsonb_path_ops ialah pilihan yang lebih baik.
Ia mencincang keseluruhan laluan kunci+nilai menjadi entri indeks tunggal, jadi indeks tersebut lebih kecil dan biasanya lebih pantas untuk carian @>, @? dan @@. Pertukarannya: ia tidak menyokong operator kewujudan kunci ?, ?|, ?& yang berdiri sendiri.
CREATE INDEX idx_orders_data_path
ON orders USING gin (data jsonb_path_ops);
-- Great for: data @? '$.items[*] ? (@.price > 100)'
-- Not for: data ? 'status'Indeks Ungkapan untuk Laluan Skalar yang Kerap Digunakan
GIN sesuai untuk carian containment yang fleksibel. Namun, jika anda sentiasa menapis berdasarkan satu nilai skalar — katakan status — indeks ungkapan B-tree yang disasarkan pada teks yang diekstrak adalah lebih kecil serta menyokong pengisihan dan imbasan julat.
- Ekstrak sekali dengan
(data->>'status')dan indekskan ungkapan tersebut. - Klausa
WHEREpertanyaan mesti menggunakan ungkapan yang sama supaya perancang dapat menggunakannya.
Gunakan GIN untuk pertanyaan "adakah dokumen mengandungi X?" dan indeks ungkapan B-tree untuk "sama dengan / disusun mengikut medan ini".
CREATE INDEX idx_orders_status
ON orders ((data->>'status'));
SELECT id FROM orders
WHERE data->>'status' = 'shipped'
ORDER BY (data->>'status');Semakan Pantas
Anda memerlukan indeks GIN yang mempercepatkan predikat laluan JSON seperti data @? '$.items[*] ? (@.price > 100)' dan anda mahukan indeks yang paling kecil serta paling pantas. Anda tidak memerlukan operator kewujudan kunci kendiri ?. Indeks manakah yang patut anda cipta?
Rumusan
Anda telah belajar cara menanya JSONB dengan bahasa laluan SQL/JSON dan cara menjadikannya pantas:
- Navigasi dari
$menggunakan titik untuk kunci dan[*]untuk tatasusunan. - Tapis dengan
? (@ ... ), menggunakan==untuk kesamaan dan&&/||untuk menggabungkan predikat. - Ekstrak padanan dengan
jsonb_path_query/jsonb_path_query_array. - Uji dalam klausa WHERE dengan
@?(penapis di dalam laluan) dan@@(laluan ialah predikat). - Indeks dengan GIN:
jsonb_opslalai untuk fleksibiliti penuh, ataujsonb_path_opsuntuk containment dan carian laluan yang lebih kecil serta pantas; gunakan indeks ungkapan B-tree apabila anda berulang kali menapis atau mengisih berdasarkan satu medan skalar.
Pilih indeks yang sepadan dengan corak capaian anda, dan sentiasa sahkan dengan EXPLAIN ANALYZE.
Pelajari SQL dengan tutor kecerdasan buatan — percuma
Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.
- Kursus
- 22
- Pelajaran
- 88
Soalan Lazim
Adakah pelajaran “Membuat Pertanyaan JSONB dengan JSONPath” percuma?
Ya — sebanyak 3 pelajaran dalam laluan pembelajaran Prestasi PostgreSQL & Pengoptimuman Pertanyaan, termasuk “Membuat Pertanyaan JSONB dengan JSONPath”, boleh dibaca sepenuhnya secara percuma di web ini. Selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan interaktif dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Kursus Prestasi PostgreSQL & Pengoptimuman Pertanyaan merangkumi sejumlah 4 pelajaran.
Apakah yang akan saya pelajari dalam “Membuat Pertanyaan JSONB dengan JSONPath”?
Gunakan ungkapan laluan SQL/JSON untuk menapis dan mengekstrak nilai bersarang dengan sokongan indeks. Anda berlatih Prestasi PostgreSQL & Pengoptimuman Pertanyaan menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.
Adakah saya memerlukan pengalaman untuk memulakan Prestasi PostgreSQL & Pengoptimuman Pertanyaan?
Tiada pengalaman terdahulu diperlukan. Pembelajaran Prestasi PostgreSQL & Pengoptimuman Pertanyaan di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 3 daripada 4.
Berapa lamakah pelajaran “Membuat Pertanyaan JSONB dengan JSONPath” diambil?
Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.
Bolehkah saya menulis dan menjalankan kod dalam pelajaran Prestasi PostgreSQL & Pengoptimuman Pertanyaan ini?
Ya. Setiap pelajaran Prestasi PostgreSQL & Pengoptimuman Pertanyaan menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.
Semua pelajaran dalam kursus ini
- Operator JSONB dan Pertanyaan Pengandungan
- GIN berbanding Indeks Ungkapan pada JSONB
- Membuat Pertanyaan JSONB dengan JSONPath
- Bila Perlu Menormalkan JSONB