Postgres: Bagaimana cara mengubah string json menjadi teks?

93

Nilai json dapat terdiri dari nilai string. misalnya.:

postgres=# SELECT to_json('Some "text"'::TEXT);
     to_json
-----------------
 "Some \"text\""

Bagaimana saya bisa mengekstrak string itu sebagai nilai teks postgres?

::TEXTtidak bekerja. Ini mengembalikan json yang dikutip, bukan string asli:

postgres=# SELECT to_json('Some "text"'::TEXT)::TEXT;
     to_json
-----------------
 "Some \"text\""

Terima kasih.

PS Saya menggunakan PostgreSQL 9.3

e79ene.dll
sumber
stackoverflow.com/q/19414361/562459 mungkin bisa membantu. Mungkin tidak.
Mike Sherrill 'Cat Recall'
Masalah serupa dengan array string, stackoverflow.com/q/45243186/287948
Peter Krauss

Jawaban:

58

Tidak ada cara di PostgreSQL untuk mendekonstruksi objek JSON skalar. Jadi, seperti yang Anda tunjukkan,

select  length(to_json('Some "text"'::TEXT) ::TEXT);

adalah 15,

Caranya adalah dengan mengubah JSON menjadi array dari satu elemen JSON, kemudian mengekstrak elemen tersebut menggunakan ->>.

select length( array_to_json(array[to_json('Some "text"'::TEXT)])->>0 );

akan mengembalikan 11.

Robert M. Lefkowitz
sumber
8
Sayang sekali json_extract_path_text()tidak bisa mereferensikan elemen root (AFAIK).
Erwin Brandstetter
3
Menariknya, ada diskusi brainstorming yang tampaknya kembali pada tahap perancangan API pada tahun 2012 di mana sebuah fungsi from_jsondiajukan, tetapi tidak diimplementasikan wiki.postgresql.org/wiki/JSON_API_Brainstorm
nikola
147

Di 9.4.4 menggunakan #>>operator berfungsi untuk saya:

select to_json('test'::text) #>> '{}';

Untuk digunakan dengan kolom tabel:

select jsoncol #>> '{}' from mytable;
Ian Timothy
sumber
2
Tampaknya menjadi solusi paling sederhana di Postgres 9.4. Namun tidak bekerja untuk 9.3.
e79ene
2
@hasen OP menyatakan dia mencoba mengekstrak teks dari nilai JSON dan to_json(...)itu hanyalah cara mudah untuk membuat nilai JSON untuk digunakan sebagai contoh dalam pernyataan satu baris singkat. Tentu Anda akan menggantinya dengan nama kolom JSON jika Anda membuat kueri tabel seperti yang Anda gambarkan. Selain itu, untuk menjernihkan titik kebingungan potensial, cast Anda (...)::textberlebihan karena #>>operator mengembalikan teks menurut definisi (dan merupakan alasan untuk menggunakan operator di tempat pertama). Anda bisa menyimpan tanda kurung tetapi melepaskan gips ::text.
Ian Timothy
1
Bisakah seseorang menjelaskan apa #>>dan '{}'sedang melakukan? Saya tidak bisa mengikuti ini dan tidak ada istilah yang ramah google. Jawaban ini memperbaiki masalah saya, saya hanya ingin tahu mengapa.
valadil
1
@valadil Dokumentasi untuk #>>operator ada di sini .
Ian Timothy
1
@valadil Dalam kasus ini, ada objek JSON level atas, atau root text. Ini mungkin terlihat seperti string tetapi ini adalah objek JSON. Untuk mengonversi objek itu dari JSON menjadi teks, gunakan #>>operator. Tetapi operator itu membutuhkan Anda untuk menentukan jalur. Jalur ke objek root tersebut adalah {}. Jadi SELECT '"test"'::jsonb #>> '{}'berarti "mendapatkan objek di jalur root dan mengubahnya menjadi teks".
Ian Timothy
3

Tuan Curious juga ingin tahu tentang ini. Selain #>> '{}'operator, di 9.6+ seseorang bisa mendapatkan nilai string jsonb dengan ->>operator:

select to_jsonb('Some "text"'::TEXT)->>0;
  ?column?
-------------
 Some "text"
(1 row)

Jika salah satu memiliki nilai json, maka solusinya adalah memasukkan ke jsonb terlebih dahulu:

select to_json('Some "text"'::TEXT)::jsonb->>0;
  ?column?
-------------
 Some "text"
(1 row)
Tuan Penasaran
sumber
0

Cara mudah untuk melakukan ini:

SELECT  ('[' || to_json('Some "text"'::TEXT) || ']')::json ->> 0;

Cukup ubah string json menjadi daftar json

Zhemin Zhou
sumber
0

- >> bekerja untukku.

versi postgres:

<postgres.version>11.6</postgres.version>

Pertanyaan:

select object_details->'valuationDate' as asofJson, object_details->>'valuationDate' as asofText from MyJsonbTable;

Keluaran:

  asofJson       asofText
"2020-06-26"    2020-06-26
"2020-06-25"    2020-06-25
"2020-06-25"    2020-06-25
"2020-06-25"    2020-06-25
Surinder
sumber
Terima kasih telah menunjukkan, saya mengoreksi versi di atas
Surinder
Pertanyaan asli adalah bagaimana mendapatkan nilai string JSON sebagai teks dengan (tanpa kunci objek). Jawaban ini hanyalah perbedaan antara ->dan ->>saat menggunakan kunci. Lihat jawaban ini atau jawaban ini .
Ian Timothy