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\""

Спасибо.

PS Я использую PostgreSQL 9.3



Аналогичная проблема с массивом строк, stackoverflow.com/q/45243186/287948
Питер Краусс

Ответы:


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).
Эрвин Брандштеттер

3
Интересно, был мозговой штурм обсуждение , видимо , снова на стадии проектирования API в 2012 году , в котором функция from_jsonполучила предложенного, но не реализован wiki.postgresql.org/wiki/JSON_API_Brainstorm
Nikola

147

В 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.
Ян Тимоти

1
Может кто разобрать, что #>>и '{}'делаем? Я не совсем понимаю это, и ни один термин не подходит для Google. Этот ответ устранил мою проблему, я просто хочу знать, почему.
валадил

1
@valadil Документация для #>>оператора находится здесь .
Ян Тимоти,

1
@valadil В данном случае это объект JSON верхнего уровня или корня text. Это может выглядеть как строка, но это объект JSON. Чтобы преобразовать этот объект из JSON в текст, используйте #>>оператор. Но этому оператору нужно указать путь. Путь к этому корневому объекту - {}. Это SELECT '"test"'::jsonb #>> '{}'означает «получить объект по корневому пути и преобразовать его в текст».
Ян Тимоти,

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

Спасибо за указание, я исправил версию выше
Суриндер

Исходный вопрос заключается в том, как получить значение строки JSON в виде текста с (без ключа объекта). Этот ответ представляет собой разницу между использованием ключа ->и ->>при его использовании. См. Этот ответ или этот ответ .
Ян Тимоти,
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.