Postgres: Jak przekonwertować ciąg json na tekst?


93

Wartość Json może składać się z wartości ciągu. na przykład.:

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

Jak mogę wyodrębnić ten ciąg jako wartość tekstową postgres?

::TEXTnie działa. Zwraca json w cudzysłowie, a nie oryginalny ciąg:

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

Dzięki.

PS Używam PostgreSQL 9.3



Podobny problem z tablicą ciągów, stackoverflow.com/q/45243186/287948
Peter Krauss

Odpowiedzi:


58

W PostgreSQL nie ma sposobu na dekonstrukcję skalarnego obiektu JSON. Tak więc, jak wskazałeś,

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

15 lat,

Sztuczka polega na przekonwertowaniu JSON na tablicę jednego elementu JSON, a następnie wyodrębnieniu tego elementu za pomocą ->>.

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

zwróci 11.


8
Szkoda, że json_extract_path_text()nie może odwoływać się do elementu głównego (AFAIK).
Erwin Brandstetter

3
Co ciekawe, nie było dyskusji mózgów najwyraźniej z powrotem na etapie projektowania API w 2012 roku, w którym funkcja from_jsondostałem proponowanych, ale nie realizowane wiki.postgresql.org/wiki/JSON_API_Brainstorm
Nikola

147

W 9.4.4 korzystanie z #>>operatora działa dla mnie:

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

Aby użyć z kolumną tabeli:

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

2
Wydaje się, że jest to najprostsze rozwiązanie w Postgres 9.4. Jednak nie działa w wersji 9.3.
e79ene

2
@hasen OP stwierdza, że ​​próbuje wyodrębnić tekst z wartości JSON i to_json(...)jest to po prostu łatwy sposób na utworzenie wartości JSON do pracy jako przykład w krótkiej jednowierszowej instrukcji. Z pewnością zastąpiłbyś ją nazwą kolumny JSON, gdybyś odpytywał tabelę zgodnie z opisem. Ponadto, aby wyjaśnić potencjalny błąd, rzutowanie (...)::textjest zbędne, ponieważ #>>operator z definicji zwraca tekst (i jest powodem używania operatora w pierwszej kolejności). Możesz zachować nawiasy, ale porzucić obsadę ::text.
Ian Timothy

1
Czy ktoś mógłby przeliterować, co #>>i '{}'robi? Nie do końca rozumiem, a żaden termin nie jest przyjazny dla Google. Ta odpowiedź rozwiązała mój problem, chcę tylko wiedzieć, dlaczego.
valadil

1
@valadil Dokumentacja dla #>>operatora jest tutaj .
Ian Timothy,

1
@valadil W tym przypadku istnieje obiekt JSON najwyższego poziomu lub root text. Może wyglądać jak ciąg znaków, ale jest to obiekt JSON. Aby przekonwertować ten obiekt z formatu JSON na tekst, użyj #>>operatora. Ale ten operator wymaga, abyś określił ścieżkę. Ścieżka do tego obiektu głównego to {}. Więc SELECT '"test"'::jsonb #>> '{}'oznacza „uzyskać obiekt na ścieżce root i przekonwertować go do tekstu”.
Ian Timothy,

3

Pan Ciekawski też był tego zaciekawiony. Oprócz #>> '{}'operatora, w 9.6+ można uzyskać wartość łańcucha jsonb za pomocą ->>operatora:

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

Jeśli ktoś ma wartość json, rozwiązaniem jest najpierw rzutowanie na jsonb:

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

0

Prosty sposób na zrobienie tego:

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

Po prostu przekonwertuj ciąg json na listę json


0

- >> działa na mnie.

wersja postgres:

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

Pytanie:

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

Wynik:

  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

Dzięki za zwrócenie uwagi, poprawiłem powyższą wersję
Surinder

Pierwotne pytanie brzmi, jak uzyskać wartość ciągu JSON jako tekst z (bez klucza obiektu). Ta odpowiedź jest po prostu różnicą między ->i ->>podczas korzystania z klucza. Zobacz tę odpowiedź lub tę odpowiedź .
Ian Timothy
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.