如何将文本转换为jsonB

时间:2017-01-29 19:03:01

标签: postgresql

在Postgres(版本9.6)中将任何文本(或varchar)转换为jsonB类型的正确方法是什么?

例如,我在这里使用两种方法,结果不同:

方法1:

dev=# select '[{"field":15,"operator":0,"value":"1"},{"field":15,"operator":0,"value":"2"},55]'::jsonb;
                                            jsonb                                             
----------------------------------------------------------------------------------------------
 [{"field": 15, "value": "1", "operator": 0}, {"field": 15, "value": "2", "operator": 0}, 55]
(1 row)

方法2,它不能产生预期的结果,顺便说一下:

dev=# select to_jsonb('[{"field":15,"operator":0,"value":"1"},{"field":15,"operator":0,"value":"2"},55]'::text);
                                              to_jsonb                                              
----------------------------------------------------------------------------------------------------
 "[{\"field\":15,\"operator\":0,\"value\":\"1\"},{\"field\":15,\"operator\":0,\"value\":\"2\"},55]"
(1 row)

dev=# 

这里,它被转换为字符串,而不是数组。 为什么第二种方法不能创建数组?

3 个答案:

答案 0 :(得分:6)

根据Postgres documentation

  

<强> to_jsonb(anyelemnt)

     

以json或jsonb的形式返回值。阵列和复合材料是   转换(递归)到数组和对象;否则,如果有的话   从类型转换为json,将使用转换函数   执行转换;否则,产生标量值。任何   除了数字,布尔值或空值之外的标量类型,文本   将使用表示形式,使其成为有效的json   或jsonb值。

恕我直言,你提供了一个JSON格式的字符串,那么你应该使用第一种方法。

to_json('Fred said "Hi."'::text)  --> "Fred said \"Hi.\""

如果您尝试使用to_json(text)获取元素数组,则会出现下一个错误:

select *
from jsonb_array_elements_text(to_jsonb('[{"field":15,"operator":0,"value":"1"},{"field":15,"operator":0,"value":"2"},55]'::text));
  

无法从标量中提取元素

但如果你之前把它投到了json:

select *
from jsonb_array_elements_text(to_jsonb('[{"field":15,"operator":0,"value":"1"},{"field":15,"operator":0,"value":"2"},55]'::json));

+--------------------------------------------+
|                    value                   |
+--------------------------------------------+
| {"field": 15, "value": "1", "operator": 0} |
+--------------------------------------------+
| {"field": 15, "value": "2", "operator": 0} |
+--------------------------------------------+
| 55                                         |
+--------------------------------------------+

答案 1 :(得分:1)

如果您的文本只是json格式的文本,则可以像这样将其显式转换为json / jsonb:

选择'{“ a”:“ b”}':: jsonb

答案 2 :(得分:0)

原子类型转换和CSV到JSONb

开放数据应用程序中的典型解析问题是将CSV(或类似CSV)文本逐行解析为JSONB正确(原子)数据类型。数据类型可以用SQL行话(“ int”,“ text”,“ float”等)或JSON行话(“ string”,“ number”)定义:

CREATE FUNCTION csv_to_jsonb(
  p_info text,           -- the CSV line
  coltypes_sql text[],   -- the datatype list
  rgx_sep text DEFAULT '\|'  -- CSV separator, by regular expression
) RETURNS JSONb AS $f$
  SELECT to_jsonb(a) FROM (
      SELECT array_agg(CASE
          WHEN tp IN ('int','integer','smallint','bigint') THEN to_jsonb(p::bigint)
          WHEN tp IN ('number','numeric','float','double') THEN  to_jsonb(p::numeric)
          WHEN tp='boolean' THEN to_jsonb(p::boolean)
          WHEN tp IN ('json','jsonb','object','array') THEN p::jsonb
          ELSE to_jsonb(p)
        END) a
      FROM regexp_split_to_table(p_info,rgx_sep) WITH ORDINALITY t1(p,i)
      INNER JOIN unnest(coltypes_sql) WITH ORDINALITY t2(tp,j)
      ON i=j
  ) t
$f$ language SQL immutable;

-- Example:
SELECT csv_to_jsonb(
  '123|foo bar|1.2|true|99999|{"x":123,"y":"foo"}',
  array['int','text','float','boolean','bigint','object']
);
-- results  [123,   "foo bar", 1.2,    true, 99999,  {"x": 123, "y": "foo"}]
-- that is: number, string,   number,  true, number, object