You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL中JSONB列:从字符串数组迁移至对象数组

解决方案

直接用一条UPDATE语句就能完成所有元素的转换,无需逐个索引手动处理:

UPDATE public.metadata
SET metadata = jsonb_set(
    -- 确保items对象存在,不存在则创建空对象
    COALESCE(metadata -> 'items', '{}'::jsonb) || metadata,
    '{items, umbrella}',
    -- 处理Umbrella数组,生成目标对象数组
    (
        SELECT jsonb_agg(
            jsonb_build_object(
                'color', split_part(elem.value::text, '|', 1),
                'pattern', split_part(elem.value::text, '|', 2)
            )
        )
        FROM jsonb_array_elements(metadata -> 'Umbrella') AS elem
    )::jsonb,
    -- 若umbrella键已存在则覆盖
    true
);

关键逻辑拆解:

  • jsonb_array_elements(metadata -> 'Umbrella'):将原数组的每个元素拆分为独立行,实现遍历所有元素的效果。
  • split_part(elem.value::text, '|', 1/2):按|分割字符串,分别提取颜色和图案值。
  • jsonb_build_object('color', ..., 'pattern', ...):把拆分后的字符串组装成目标格式的JSON对象。
  • jsonb_agg(...):将处理后的单个对象重新聚合为数组。
  • jsonb_set(..., true):第三个参数设为true,表示items->umbrella存在则覆盖、不存在则创建。

可选优化:过滤无效行

如果表中存在Umbrella字段为空或非数组的情况,可添加WHERE条件避免无效更新:

UPDATE public.metadata
SET metadata = jsonb_set(
    COALESCE(metadata -> 'items', '{}'::jsonb) || metadata,
    '{items, umbrella}',
    (
        SELECT jsonb_agg(
            jsonb_build_object(
                'color', split_part(elem.value::text, '|', 1),
                'pattern', split_part(elem.value::text, '|', 2)
            )
        )
        FROM jsonb_array_elements(metadata -> 'Umbrella') AS elem
    )::jsonb,
    true
)
WHERE metadata ? 'Umbrella' -- 仅处理存在Umbrella字段的行
  AND jsonb_typeof(metadata -> 'Umbrella') = 'array'; -- 确保字段是数组类型

内容的提问来源于stack exchange,提问作者Gabriela83

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 14:25:15