PostgreSQL 9.2 - 将TEXT json字符串转换为json / hstore类型

时间:2013-04-18 04:14:48

标签: postgresql postgresql-9.2

我有一个包含有效JSON字符串的TEXT列。

CREATE TABLE users(settings TEXT);

INSERT INTO users VALUES ('{"language":"en","gender":"male"}');
INSERT INTO users VALUES ('{"language":"fr","gender":"female"}');
INSERT INTO users VALUES ('{"language":"es","gender":"female"}');
INSERT INTO users VALUES ('{"language":"en","gender":"male"}');

我想将一些字段转换为可查询的格式。

每个字段REGEXP_REPLACE会有(language字段和gender字段。但由于它是有效的JSON,有没有办法:

  • 转换为JSON类型
  • 转换为hstore类型
  • 或任何其他可行方式

SQLFiddle:http://sqlfiddle.com/#!12/54823

7 个答案:

答案 0 :(得分:31)

SELECT cast(settings AS json) from users;

答案 1 :(得分:20)

或者以比Reza最短的方式:

SELECT settings::json FROM users;

然后,例如选择语言:

SELECT settings::json->>'language' FROM users;

有关official documentation的详细信息。

答案 2 :(得分:14)

以下是来自Postgresql: Converting TEXT columns to JSON的解决方案:

ALTER TABLE table1 ALTER COLUMN col1 TYPE JSON USING col1::JSON;

答案 3 :(得分:3)

如果需要索引,请创建一个以json为输入的不可变函数,并以pl语言生成所需的字段,例如:

create function extract_language(text) returns text as $$
  -- parse $1 as json
  -- return $1.language
$$ language whatever immutable;

然后在表达式上添加一个索引:

create index users_language on users(extract_language(settings));

然后(可能)在索引中使用索引,例如:

select * from users where extract_language(settings) = 'en';

答案 4 :(得分:0)

因此,我遇到了文本为JSON的问题。如果您有此问题,请改用此查询。其中COLUMN是包含JSONB或JSON数据类型的列,而ATTRIBUTE是要转换为JSON的JSON属性(字符串)。

文字看起来像这样, “ {\” junk5 \“:283774663,\” junk2 \“:0,\” junk1 \“:1218478497,\” junk3 \“:1923,\” junk4 \“:63278342}”

SELECT CAST(TRIM(both '"' from jsonstring) as JSON)
FROM (
    SELECT REPLACE(cast(COLUMN->'ATTRIBUTE' as text), '\"', '"')
    as jsonString from TABLE where cast(COLUMN->'ATTRIBUTE' as text)LIKE '%\\%'
) as JSON_CONVERTING

答案 5 :(得分:0)

添加到另一条评论中,这是查询中的一线内容(无需更新)

regexp_replace(trim(both '"' from settings::text), '\\"', '"', 'g')::json as column_name;

答案 6 :(得分:0)

如果您的列已经是 json 并且在其根级别包含字符串,则 ::jsonb 将不起作用。 这是将此类字符串转换为 JSON 的一个 liner:

SELECT (settings #>> '{}')::jsonb -> 'language' from users;

我在 here

中找到了这个答案

该语句首先通过给定空路径的 #>> 运算符将根级字符串提取为文本。请注意,简单地将此类字符串转换为文本 (::text) 是行不通的,因为它会转义所有引号。 接下来将这样提取的字符串解析为 json 对象 (::jsonb)。

此查询的另一种版本是将 json 字符串放入数组中,然后将其第一个元素提取为文本:

select cast(json_build_array(settings)->>0 as json)

要解决此问题,您也可以使用以下命令将根级别的所有带有字符串的字段转换为 json:

UPDATE users
SET
    settings = settings #>>'{}'::jsonb
WHERE settings ->> 'language' is  NULL