postgresql 从jsonb值中删除键和/或数组元素

zf2sa74q  于 2024-01-07  发布在  PostgreSQL
关注(0)|答案(1)|浏览(235)

我们在表metaTable中有一个列metajsonb

  1. {
  2. "records": {
  3. record1: {
  4. "GUID-1": {
  5. values: ["GUID-value-1", "GUID-value-2", "GUID-value-3"],
  6. type: "..."
  7. },
  8. "GUID-2": {
  9. values: ["GUID-value-4", "GUID-value-5"],
  10. type: "..."
  11. },
  12. "GUID-3": {
  13. values: ["GUID-value-6"],
  14. type: "..."
  15. },
  16. "GUID-4": {
  17. values: ["GUID-value-7"],
  18. type: "..."
  19. }
  20. }
  21. },
  22. "miscellaneous": {
  23. .....
  24. }
  25. }

字符串
"GUID-1""GUID-2""GUID-3""GUID-4"是关键。
"GUID-value-1""GUID-value-2""GUID-value-3""GUID-value-4""GUID-value-5""GUID-value-6""GUID-value-7"是值。

  • 键和值都是唯一的。*

我们尝试从JSON文档中删除在给定数组中列出的键和/或嵌套数组元素。例如:
["GUID-3", "GUID-value-4", "GUID-value-1", "GUID-value-2", "GUID-value-3", "GUID-value-7", "GUID-4", "random-GUID1", "random-GUID2"]
预期结果:

  1. {
  2. "records": {
  3. record1: {
  4. "GUID-2": {
  5. values: ["GUID-value-5"],
  6. type: "..."
  7. }
  8. }
  9. },
  10. "miscellaneous": {
  11. .....
  12. }
  13. }


注1:"GUID-1"被删除,因为数组"values"是空的。
注2:此SQL将应用于每一行。
我试过:

  1. update metaTable
  2. set "meta" =
  3. json_set("meta", '{records, record1, GUID-1, values}', ("meta" -> 'records' -> 'record1' -> 'GUID-1' -> values) - '{GUID-value-1, GUID-value-2", GUID-value-3}'::text[])


只有当我已经知道GUID- 1是键,GUID-value-1, GUID-value-2, and GUID-value-3是值时,这才有效。
有没有一种通用的方法可以在一个SQL查询中完成它,而不需要事先弄清楚每个查询的角色?

anauzrmj

anauzrmj1#

这里有一个基本的解决方案:

  1. SELECT t.id, jsonb_pretty(jsonb_set(meta, '{records,record1}', r.upd_rec))
  2. FROM tbl t
  3. CROSS JOIN (
  4. SELECT '{GUID-3,GUID-value-4,GUID-value-1,GUID-value-2,GUID-value-3,GUID-value-7,GUID-4,random-GUID1,random-GUID2}'::text[] -- input here!
  5. ) d(del_arr)
  6. CROSS JOIN LATERAL (
  7. SELECT jsonb_object_agg(r.k, jsonb_set(r.v, '{values}', (r.v -> 'values') - d.del_arr))
  8. FROM jsonb_each(t.meta #> '{records,record1}') r(k,v)
  9. WHERE r.k <> ALL (d.del_arr)
  10. AND (r.v -> 'values') - d.del_arr <> jsonb '[]'
  11. ) r(upd_rec)
  12. ORDER BY t.id;

字符串
fiddle
你可以从它构建你的UPDATE。有很多需要解释的。它可以进一步优化。
但我觉得这太具体了,对公众没有用处。

展开查看全部

相关问题