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

Posted

技术标签:

【中文标题】PostgreSQL 9.2 - 将 TEXT json 字符串转换为 json/hstore 类型【英文标题】:PostgreSQL 9.2 - Convert TEXT json string to type json/hstore 【发布时间】:2013-04-18 04:14:48 【问题描述】:

我有一个包含有效 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

【问题讨论】:

请求的功能是 9.3 中有趣的功能之一。我阅读了一些文章,其中使用 pl/js8 进行了描述postgresonline.com/journal/archives/… 谢谢。我还发现我可以通过将其转换为 JSON 来完成第一个:settings::json。但它不是可查询的。用正则表达式解决。 仅供参考,PostgreSQL 9.2 adpgtech.blogspot.co.nz/2013/04/… 有一个 9.3 JSON 函数增强的反向移植@ 【参考方案1】:
SELECT cast(settings AS json) from users;

7 年后编辑

我强烈建议您不要使用非结构化列,除非您的数据是非结构化的。 RDBMS 有很长的路要走。我们搭建了一个相当大的平台,把用户设置当成一个json列,结果它变成了一个多年后需要清理的垃圾抽屉

【讨论】:

我需要完全相同的东西。这很好地完成了这项工作。也就是说,虽然我正在查询一个相对较小的数据集,但我无法说出它的性能如何。 我希望一开始就在文档中说明这一点。或者,如果我过度阅读了,我希望它更加突兀。将数据库中的 varchar 转换为 json 需要很长时间。谢谢你的帖子。 我记得这个 used 可以工作,但最近我得到了invalid input syntax 返回,似乎找不到有用的文档来说明如何将“有效”字符串化 JSON 写入varchar 字段【参考方案2】:

或者比 Reza 更简洁:

SELECT settings::json FROM users;

然后,例如选择语言:

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

更多详情请关注official documentation。

【讨论】:

我知道这已经很老了,但是:如何在文本中搜索特殊字段,比如说 WHERE settings::json = 'team_id':team_id (也就是说要搜索一个设置文本中的特定字段)? @Pille 设置::json ->> 'team_id' = team_id【参考方案3】:

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

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

【讨论】:

这需要重写表吗? 不确定这是否能解决问题,更改类型需要重构表【参考方案4】:

所以我遇到了文本是 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

【讨论】:

这是我的一个班轮:update users set settings = regexp_replace(trim(both '"' from settings), '\\"', '"', 'g')::json; 如果被转换的 json 中有另一个 json 作为字符串,这将失败。更安全的方法是将字符串提取为文本并将其转换为 json:`select settings #>>''::jsonb from users;。有关详细说明,请参阅下面的答案。【参考方案5】:

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

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

【讨论】:

难以置信。这正是我所需要的。我非常自豪和谦卑地成为您对这个答案的第一个支持。 :-) 继续做好你的工作,先生。 谢谢Chirs 的客气话!你让我开心:)。 同意!!!你通过邮局为我节省了美元!谢谢!【参考方案6】:

如果您需要对其进行索引,请创建一个不可变函数,该函数将 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';

【讨论】:

【参考方案7】:

添加到另一条评论,这里是查询中的单行符(无需更新)

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

【讨论】:

以上是关于PostgreSQL 9.2 - 将 TEXT json 字符串转换为 json/hstore 类型的主要内容,如果未能解决你的问题,请参考以下文章

postgresql 9.2 中 varchar(n) 的最大长度是多少,哪个最好使用 varchar(n) 或 text?

如何在 Django 中使用 PostgreSQL 9.2 JSON 数据类型?

在RedHat中从postgresql 9.2升级到9.6时unix_socket_directory出错

在 postgreSQL 9.2 上编辑 postgresql.conf 文件?

Postgresql 9.2 错误与 group by 未出现在 postgresql 12 中

播放框架中未解决的 postgresql 9.2 jar 依赖关系