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,有没有办法:
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 文件?