Postgres: วิธีแปลงสตริง json เป็นข้อความ


93

ค่า Json อาจประกอบด้วยค่าสตริง เช่น.:

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

ฉันจะแยกสตริงนั้นเป็นค่าข้อความ postgres ได้อย่างไร

::TEXTไม่ทำงาน ส่งคืน json ที่ยกมาไม่ใช่สตริงเดิม:

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

ขอบคุณ.

ปล. ฉันใช้ PostgreSQL 9.3


stackoverflow.com/q/19414361/562459อาจช่วยได้ อาจจะไม่.
Mike Sherrill 'Cat Recall'

ปัญหาที่คล้ายกันกับอาร์เรย์ของสตริงstackoverflow.com/q/45243186/287948
Peter Krauss

คำตอบ:


58

ไม่มีวิธีใดใน PostgreSQL ในการแยกโครงสร้างออบเจ็กต์ JSON สเกลาร์ ดังที่คุณชี้ให้เห็น

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

คือ 15

เคล็ดลับคือการแปลง JSON เป็นอาร์เรย์ขององค์ประกอบ JSON หนึ่งรายการจากนั้นแยกองค์ประกอบนั้นโดยใช้->>.

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

จะกลับมา 11.


8
น่าเสียดายที่json_extract_path_text()ไม่สามารถอ้างอิงองค์ประกอบราก (AFAIK) ได้
Erwin Brandstetter

3
ที่น่าสนใจคือมีการอภิปรายระดมความคิดที่เห็นได้ชัดในขั้นตอนการออกแบบ API ในปี 2012 ซึ่งfrom_jsonมีการเสนอฟังก์ชั่นแต่ไม่ได้ใช้wiki.postgresql.org/wiki/JSON_API_Brainstorm
nikola

148

ใน 9.4.4 การใช้ตัว#>>ดำเนินการใช้ได้กับฉัน:

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

วิธีใช้กับคอลัมน์ตาราง:

select jsoncol #>> '{}' from mytable;

2
ดูเหมือนจะเป็นวิธีที่ง่ายที่สุดใน Postgres 9.4 อย่างไรก็ตามใช้ไม่ได้กับ 9.3
e79ene

2
@hasen OP ระบุว่าเขาพยายามดึงข้อความจากค่า JSON และto_json(...)เป็นวิธีง่ายๆในการสร้างค่า JSON เพื่อใช้เป็นตัวอย่างในคำสั่งสั้น ๆ เพียงบรรทัดเดียว แน่นอนว่าคุณจะแทนที่ด้วยชื่อคอลัมน์ JSON หากคุณกำลังค้นหาตารางตามที่คุณอธิบาย นอกจากนี้เพื่อล้างจุดที่อาจเกิดความสับสนนักแสดงของคุณ(...)::textจะซ้ำซ้อนเนื่องจากตัว#>>ดำเนินการส่งคืนข้อความตามคำจำกัดความ (และเป็นเหตุผลในการใช้ตัวดำเนินการตั้งแต่แรก) คุณสามารถเก็บวงเล็บ ::textแต่วางหล่อ
Ian Timothy

1
บางคนอาจสะกดออกสิ่งที่#>>และ'{}'กำลังทำอะไร? ฉันไม่สามารถทำตามสิ่งนี้ได้และไม่มีคำใดที่เป็นมิตรกับ Google คำตอบนี้ช่วยแก้ปัญหาของฉันได้ฉันแค่อยากรู้ว่าทำไม
valadil

1
@valadil เอกสารสำหรับ#>>ผู้ประกอบการเป็นที่นี่
Ian Timothy

1
@valadil ในกรณีนี้มีออบเจ็กต์ JSON ระดับบนสุดหรือรูtextท อาจดูเหมือนสตริง แต่เป็นออบเจ็กต์ JSON ในการแปลงวัตถุนั้นจาก JSON เป็นข้อความให้ใช้ตัว#>>ดำเนินการ แต่ตัวดำเนินการนั้นต้องการให้คุณระบุเส้นทาง {}เส้นทางไปยังวัตถุที่มีรากซึ่งเป็น ดังนั้นSELECT '"test"'::jsonb #>> '{}'หมายความว่า "รับวัตถุที่เส้นทางรากและแปลงเป็นข้อความ"
Ian Timothy

3

นายอยากรู้อยากเห็นเกี่ยวกับเรื่องนี้เช่นกัน นอกจากตัว#>> '{}'ดำเนินการแล้วใน 9.6+ เราสามารถรับค่าของสตริง jsonb ด้วยตัว->>ดำเนินการ:

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

หากมีค่า json วิธีแก้ปัญหาคือโยนลงใน jsonb ก่อน:

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

0

วิธีง่ายๆในการทำสิ่งนี้:

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

เพียงแค่แปลงสตริง json เป็นรายการ json


0

- >> ใช้ได้กับฉัน

รุ่น postgres:

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

คำถาม:

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

เอาท์พุต:

  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

คำถามเดิมคือวิธีรับค่าของสตริง JSON เป็นข้อความโดยใช้ (ไม่มีคีย์ออบเจ็กต์) คำตอบนี้เป็นเพียงความแตกต่างระหว่าง->และ->>เมื่อใช้คีย์ ดูคำตอบนี้หรือคำตอบนี้
Ian Timothy
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.