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

e79ene
источник
stackoverflow.com/q/19414361/562459 может помочь. Может не.
Майк Шерилл 'Cat Recall'
Аналогичная проблема с массивом строк, 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 в виде текста с (без ключа объекта). Этот ответ представляет собой разницу между использованием ключа ->и ->>при его использовании. См. Этот ответ или этот ответ .
Ян Тимоти,