Saya ingin agar PostgreSQL mengembalikan hasil kueri sebagai satu array JSON. Diberikan
create table t (a int primary key, b text);
insert into t values (1, 'value1');
insert into t values (2, 'value2');
insert into t values (3, 'value3');
Saya mau membeli sesuatu yang mirip dengan
[{"a":1,"b":"value1"},{"a":2,"b":"value2"},{"a":3,"b":"value3"}]
atau
{"a":[1,2,3], "b":["value1","value2","value3"]}
(sebenarnya akan lebih berguna untuk mengetahui keduanya). Saya telah mencoba beberapa hal seperti
select row_to_json(row) from (select * from t) row;
select array_agg(row) from (select * from t) row;
select array_to_string(array_agg(row), '') from (select * from t) row;
Dan saya merasa saya dekat, tetapi tidak benar-benar di sana. Haruskah saya melihat dokumentasi lain kecuali untuk 9.15. Fungsi dan Operator JSON ?
Ngomong-ngomong, saya tidak yakin dengan ide saya. Apakah ini keputusan desain biasa? Pemikiran saya adalah bahwa saya dapat, tentu saja, mengambil hasil (misalnya) dari 3 kueri pertama di atas dan memanipulasinya sedikit dalam aplikasi sebelum menyajikannya kepada klien, tetapi jika PostgreSQL dapat membuat objek JSON terakhir secara langsung, itu akan lebih sederhana, karena saya masih belum menyertakan ketergantungan pada pustaka JSON mana pun dalam aplikasi saya.
sumber
Jawaban:
TL; DR
untuk larik objek JSON, dan
untuk objek array JSON.
Daftar objek
Bagian ini menjelaskan cara membuat larik objek JSON, dengan setiap baris diubah menjadi satu objek. Hasilnya terlihat seperti ini:
9.3 dan lebih tinggi
The
json_agg
Fungsi menghasilkan hasil ini keluar dari kotak. Ini secara otomatis mencari cara untuk mengubah inputnya menjadi JSON dan menggabungkannya menjadi sebuah array.Tidak ada
jsonb
(diperkenalkan pada 9.4) versijson_agg
. Anda dapat menggabungkan baris menjadi array dan kemudian mengonversinya:atau gabungkan
json_agg
dengan pemeran:Pengujian saya menunjukkan bahwa menggabungkan mereka ke dalam array terlebih dahulu sedikit lebih cepat. Saya menduga bahwa ini karena pemeran harus mengurai seluruh hasil JSON.
9.2
9.2 tidak memiliki
json_agg
atauto_json
fungsi, jadi Anda perlu menggunakan yang lebih lamaarray_to_json
:Anda secara opsional dapat menyertakan
row_to_json
panggilan dalam kueri:Ini mengonversi setiap baris menjadi objek JSON, menggabungkan objek JSON sebagai larik, lalu mengonversi larik menjadi larik JSON.
Saya tidak dapat melihat perbedaan kinerja yang signifikan antara keduanya.
Objek daftar
Bagian ini menjelaskan cara membuat objek JSON, dengan setiap kunci menjadi kolom di tabel dan setiap nilai menjadi larik nilai kolom. Hasilnya terlihat seperti ini:
9.5 dan lebih tinggi
Kami dapat memanfaatkan
json_build_object
fungsinya:Anda juga bisa menggabungkan kolom, membuat satu baris, lalu mengubahnya menjadi objek:
Perhatikan bahwa aliasing array mutlak diperlukan untuk memastikan bahwa objek memiliki nama yang diinginkan.
Mana yang lebih jelas adalah soal opini. Jika menggunakan
json_build_object
fungsi ini, saya sangat menyarankan untuk meletakkan satu pasangan kunci / nilai pada satu baris untuk meningkatkan keterbacaan.Anda juga bisa menggunakan
array_agg
sebagai penggantijson_agg
, tetapi pengujian saya menunjukkan bahwajson_agg
sedikit lebih cepat.Tidak ada
jsonb
versi darijson_build_object
fungsi tersebut. Anda dapat menggabungkan menjadi satu baris dan mengonversi:Berbeda dengan query lain untuk jenis hasil ini,
array_agg
sepertinya menjadi sedikit lebih cepat saat digunakanto_jsonb
. Saya menduga ini karena penguraian overhead dan memvalidasi hasil JSON darijson_agg
.Atau Anda dapat menggunakan pemeran eksplisit:
The
to_jsonb
Versi memungkinkan Anda untuk menghindari pemain dan lebih cepat, menurut pengujian saya; sekali lagi, saya menduga ini karena overhead parsing dan memvalidasi hasilnya.9.4 dan 9.3
The
json_build_object
fungsi baru untuk 9,5, sehingga Anda harus agregat dan mengkonversi ke objek di versi sebelumnya:atau
tergantung pada apakah Anda ingin
json
ataujsonb
.(9.3 tidak memiliki
jsonb
.)9.2
Di 9.2, bahkan tidak
to_json
ada. Anda harus menggunakanrow_to_json
:Dokumentasi
Temukan dokumentasi untuk fungsi JSON dalam fungsi JSON .
json_agg
ada di halaman fungsi agregat .Rancangan
Jika kinerja itu penting, pastikan Anda mengukur kueri Anda terhadap skema dan data Anda sendiri, daripada mempercayai pengujian saya.
Apakah itu desain yang bagus atau tidak sangat tergantung pada aplikasi spesifik Anda. Dalam hal pemeliharaan, saya tidak melihat ada masalah khusus. Ini menyederhanakan kode aplikasi Anda dan berarti lebih sedikit yang harus dipertahankan di bagian aplikasi tersebut. Jika PG dapat memberikan hasil yang Anda butuhkan di luar kotak, satu-satunya alasan yang dapat saya pikirkan untuk tidak menggunakannya adalah pertimbangan kinerja. Jangan menemukan kembali roda dan semuanya.
Nulls
Fungsi agregat biasanya memberikan kembali
NULL
ketika mereka beroperasi pada baris nol. Jika ini adalah kemungkinan, Anda mungkin ingin menggunakanCOALESCE
untuk menghindarinya. Beberapa contoh:Atau
Kredit ke Hannes Landeholm untuk menunjukkan ini
sumber
to_json
sebagai penggantirow_to_json
danarray_to_json
SELECT json_agg((column1, column2, ...)) FROM t
- perhatikan tanda kurung tambahan. Ini mungkin tidak terlihat jelas "di luar kotak".Juga jika Anda ingin bidang yang dipilih dari tabel dan digabungkan kemudian sebagai array.
Hasilnya akan datang.
sumber