简体   繁体   English

如何更新 postgres 中的特定 JSONB 数组元素

[英]How to update specific JSONB array elements in postgres

In a table (tableA), I have a column (columnA) type jsonb array eg在表(tableA)中,我有一个列(columnA)类型的 jsonb 数组,例如

[
  {
    "pinned_at": blah.sdf,
    "pinned_by": "ford@gm.com",
  },
  {
    "pinned_at": blah.dsf,
    "pinned_by": "vladyslav.kistruga@gen.tech",
  },
  {
    "pinned_at": 1633874350.2,
    "pinned_by": "denys.voloshyn@gen.tech",
  },
  {
    "pinned_at": 1625294401.79845,
    "pinned_by": "robert.john@google.com",
  },
  {
    "pinned_at": blah,
    "pinned_by": "john@google.com",
  },
  {
    "pinned_at": blah.dsf,
    "pinned_by": "apple@banana.com",
  }
]

A little bit unsure how to query for every pinned_by key.有点不确定如何查询每个 pinned_by 键。 Ultimately, I want to update all the emails that are not google.com so that the end result would look like:最终,我想更新所有不是 google.com 的电子邮件,以便最终结果如下所示:

[
  {
    "pinned_at": blah.sdf,
    "pinned_by": "dasadgsf@googlefake.com",
  },
  {
    "pinned_at": blah.dsf,
    "pinned_by": "dsfjldjs@googlefake.com",
  },
  {
    "pinned_at": 1633874350.2,
    "pinned_by": "abcfjsl@googlefake.com",
  },
  {
    "pinned_at": 1625294401.79845,
    "pinned_by": "robert.john@google.com",
  },
  {
    "pinned_at": blah,
    "pinned_by": "john@google.com",
  },
  {
    "pinned_at": blah.dsf,
    "pinned_by": "asdinaof@googlefake.com",
  }
]

I've tried updating using this query, but to no avail.我尝试使用此查询进行更新,但无济于事。 I feel like I'm close but am missing some specific value:我觉得我很接近,但缺少一些特定的价值:

UPDATE tableA SET columnA = s.json_array FROM (SELECT jsonb_agg(CASE WHEN columnA->>'pinned_by' !~ 'google\.com"' THEN jsonb_set(columnA, '{pinned_by}',  substr(md5(random()::text), 0, 25)) ELSE columnA END) as json_array FROM tableA, jsonb_array_elements(columnA) columnA) s;```

You can build query like below (My sample table has id for group by and update record)您可以像下面这样构建查询(我的示例表具有分组依据和更新记录的id

Demo 演示

UPDATE tableA u_a
SET columnA = tmp.json_array
FROM (
  SELECT 
    a.id,
    jsonb_agg(
      CASE 
        WHEN e.value ->> 'pinned_by' !~ 'google\.com' THEN jsonb_set(e.value, '{pinned_by}',  to_jsonb(substr(md5(random()::text), 0, 25) || '@googlefake.com')) 
        ELSE e.value 
      END
    ) AS json_array
  FROM tableA a
  CROSS JOIN jsonb_array_elements(columnA) e
  GROUP BY 1
) AS tmp
WHERE
  u_a.id = u_a.id

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM