将列中的键值转换为 hstore 或 jsonb 列的正则表达式?
regex to convert key values in a column to an hstore or jsonb column?
我有一个数据库,其中有一个名为 activity
的 table 和一个名为 detail
的列,该列不幸地表示为 key/value 对:
Key ID=[813],\n
Key Name=[Name of Key],\n
Some Field=[2732],\n
Another Field=[2751],\n
Description=[A text string here],\n
Location=[sometext],\n
Other ID=[2360578],\n
从上面的格式中可能很清楚,这是每行一个值,\n 是一个换行符,所以总是有一个额外的换行符。我试图避免让外部程序处理这些数据,所以我正在研究 postgresql 的正则表达式函数。目标是将其转换为 jsonb 或 hstore 列,我真的不在乎哪个。
table 的架构如下:
CREATE TABLE activity
(
id integer NOT NULL,
activity_type integer NOT NULL,
ts timestamp with time zone,
detail text NOT NULL,
details_hstore hstore,
details_jsonb jsonb,
CONSTRAINT activity_pkey PRIMARY KEY (id),
);
所以我想 运行 一个 UPDATE
,我用来自 detail
的处理数据更新 details_jsonb
或 details_hstore
。
这个:
select regexp_matches(activity.detail, '(.*?)=\[(.*?)\]\,[\r|\n]', 'g') as val from activity
给我这些单独的行(这是来自 pgadmin,我假设这些都是字符串):
{"Key ID",813}
{"Key Name","Name of Key"}
{"Some Field",2732}
{"Another Field",2751}
{Description,"A text string here"}
{Location,sometext}
{"Other ID",2360578}
我不是正则表达式高手,但我认为我需要某种分组。此外,它作为某种文本数组返回,但我真正想要的是 jsonb
{"Key ID": "813", "Key Name": "Name of Key"}
甚至更好,如果它只是一个数字那么
{"Key ID": 813, "Key Name": "Name of Key"}
and/or 相当于 hstore。
我觉得我离这个目标还有很多 regex-in-postgres 概念。
- 首先是如何将所有对放在某种数组或其他东西中,而不是作为单独的行。
- 其次,我能否确定它是否是一个数字,并可选择在字符串周围获取“”,而在 jsonb 或 hstore 的数字周围什么都没有
- 第三,把它当作某种 string/text
- 第四,如何使用更新
将其写入另一个jsonb/hstore字段
这种正则表达式更新太多以至于无法在更新中工作吗?即 update activity set details_jsonb = [[insane regex here]]
? hstore 也是一个选项(虽然我喜欢 jsonb 有类型),所以如果像 hstore(text[]) 这样的 hstore 函数更容易,那也很好。
我是不是疯了,我是否需要只编写一个不在 postgresql 中的外部进程来执行此操作?
我会先将单个值拆分成多行。然后可以将每一行转换为一个数组,从中可以将其聚合到一个 JSON 对象中:
select string_to_array(regexp_replace(t.line, '(^\s+)|(\s+$)', '', 'g'), '=')
from activity a, regexp_split_to_table(a.detail, ',\s*\n') t (line)
这个returns下面的:
element
------------------------------------
{KeyID,[813]}
{"Key Name","[Name of Key]"}
{"Some Field",[2732]}
{"Another Field",[2751]}
{Description,"[A text string here]"}
{Location,[sometext]}
{"Other ID",[2360578]}
{}
将 detail
值拆分为多行的正则表达式可能需要一些改进。
regexp_replace(t.line, '(^\s+)|(\s+$)', '', 'g')
那里有 trim 值,然后再将它们转换为数组。
现在可以将其聚合为单个 JSON 值,或者每行可以转换为单个 hstore 值(遗憾的是没有 hstore_agg()
)
with activity (detail) as (
values (
'Key ID=[813],
Key Name=[Name of Key],
Some Field=[2732],
Another Field=[2751],
Description=[A text string here],
Location=[sometext],
Other ID=[2360578],
')
), elements (element) as (
select string_to_array(regexp_replace(t.line, '\s', ''), '=')
from activity a, regexp_split_to_table(a.detail, ',') t (line)
)
select json_agg(jsonb_object(element))
from elements
where cardinality(element) > 1 -- this removes the empty line
上面returns一个JSON对象:
[ { "KeyID" : "[813]" },
{ "Key Name" : "[Name of Key]" },
{ "Some Field" : "[2732]" },
{ "Another Field" : "[2751]" },
{ "Description" : "[A text string here]" },
{ "Location" : "[sometext]" },
{ "Other ID" : "[2360578]" }
]
我有一个数据库,其中有一个名为 activity
的 table 和一个名为 detail
的列,该列不幸地表示为 key/value 对:
Key ID=[813],\n
Key Name=[Name of Key],\n
Some Field=[2732],\n
Another Field=[2751],\n
Description=[A text string here],\n
Location=[sometext],\n
Other ID=[2360578],\n
从上面的格式中可能很清楚,这是每行一个值,\n 是一个换行符,所以总是有一个额外的换行符。我试图避免让外部程序处理这些数据,所以我正在研究 postgresql 的正则表达式函数。目标是将其转换为 jsonb 或 hstore 列,我真的不在乎哪个。
table 的架构如下:
CREATE TABLE activity
(
id integer NOT NULL,
activity_type integer NOT NULL,
ts timestamp with time zone,
detail text NOT NULL,
details_hstore hstore,
details_jsonb jsonb,
CONSTRAINT activity_pkey PRIMARY KEY (id),
);
所以我想 运行 一个 UPDATE
,我用来自 detail
的处理数据更新 details_jsonb
或 details_hstore
。
这个:
select regexp_matches(activity.detail, '(.*?)=\[(.*?)\]\,[\r|\n]', 'g') as val from activity
给我这些单独的行(这是来自 pgadmin,我假设这些都是字符串):
{"Key ID",813}
{"Key Name","Name of Key"}
{"Some Field",2732}
{"Another Field",2751}
{Description,"A text string here"}
{Location,sometext}
{"Other ID",2360578}
我不是正则表达式高手,但我认为我需要某种分组。此外,它作为某种文本数组返回,但我真正想要的是 jsonb
{"Key ID": "813", "Key Name": "Name of Key"}
甚至更好,如果它只是一个数字那么
{"Key ID": 813, "Key Name": "Name of Key"}
and/or 相当于 hstore。
我觉得我离这个目标还有很多 regex-in-postgres 概念。
- 首先是如何将所有对放在某种数组或其他东西中,而不是作为单独的行。
- 其次,我能否确定它是否是一个数字,并可选择在字符串周围获取“”,而在 jsonb 或 hstore 的数字周围什么都没有
- 第三,把它当作某种 string/text
- 第四,如何使用更新 将其写入另一个jsonb/hstore字段
这种正则表达式更新太多以至于无法在更新中工作吗?即 update activity set details_jsonb = [[insane regex here]]
? hstore 也是一个选项(虽然我喜欢 jsonb 有类型),所以如果像 hstore(text[]) 这样的 hstore 函数更容易,那也很好。
我是不是疯了,我是否需要只编写一个不在 postgresql 中的外部进程来执行此操作?
我会先将单个值拆分成多行。然后可以将每一行转换为一个数组,从中可以将其聚合到一个 JSON 对象中:
select string_to_array(regexp_replace(t.line, '(^\s+)|(\s+$)', '', 'g'), '=')
from activity a, regexp_split_to_table(a.detail, ',\s*\n') t (line)
这个returns下面的:
element
------------------------------------
{KeyID,[813]}
{"Key Name","[Name of Key]"}
{"Some Field",[2732]}
{"Another Field",[2751]}
{Description,"[A text string here]"}
{Location,[sometext]}
{"Other ID",[2360578]}
{}
将 detail
值拆分为多行的正则表达式可能需要一些改进。
regexp_replace(t.line, '(^\s+)|(\s+$)', '', 'g')
那里有 trim 值,然后再将它们转换为数组。
现在可以将其聚合为单个 JSON 值,或者每行可以转换为单个 hstore 值(遗憾的是没有 hstore_agg()
)
with activity (detail) as (
values (
'Key ID=[813],
Key Name=[Name of Key],
Some Field=[2732],
Another Field=[2751],
Description=[A text string here],
Location=[sometext],
Other ID=[2360578],
')
), elements (element) as (
select string_to_array(regexp_replace(t.line, '\s', ''), '=')
from activity a, regexp_split_to_table(a.detail, ',') t (line)
)
select json_agg(jsonb_object(element))
from elements
where cardinality(element) > 1 -- this removes the empty line
上面returns一个JSON对象:
[ { "KeyID" : "[813]" },
{ "Key Name" : "[Name of Key]" },
{ "Some Field" : "[2732]" },
{ "Another Field" : "[2751]" },
{ "Description" : "[A text string here]" },
{ "Location" : "[sometext]" },
{ "Other ID" : "[2360578]" }
]