来自 json 列的 Postgres select 特定嵌套键

Postgres select specific nested keys from json column

有一个 table 和 json 列,这个 json 相当大,所以我只想 filter/select 特定的嵌套键。

Json 示例:

{
   "title":{
      "nested_1":"This is nested key 1",
      "nested_2":"This is nested key 2",
      "nested_3":"This is nested key 3",
      "nested_4":"This is nested key 4",
      "nested_5":"This is nested key 5"
   },
   "description":{
      "nested_1":"This is nested key 1",
      "nested_2":"This is nested key 2",
      "nested_3":"This is nested key 3",
      "nested_4":"This is nested key 4",
      "nested_5":"This is nested key 5"
   },
   "meta":{
      "nested_1":"This is nested key 1",
      "nested_2":"This is nested key 2",
      "nested_3":"This is nested key 3",
      "nested_4":"This is nested key 4",
      "nested_5":"This is nested key 5"
   }
}

例如,我只想 select nested_3nested_5(但保留 json 结构):

{
   "title":{
      "nested_3":"This is nested key 3",
      "nested_5":"This is nested key 5"
   },
   "description":{
      "nested_3":"This is nested key 3",
      "nested_5":"This is nested key 5"
   },
   "meta":{
      "nested_3":"This is nested key 3",
      "nested_5":"This is nested key 5"
   }
}

到目前为止我尝试了什么:

select 
id,
(select json_object_agg(key, val) from (
    values 
    ('nested_3', (select json_object_agg(t.token, t.content->'nested_3') from json_each(json_col) as t(token, content))),
    ('nested_5', (select json_object_agg(t.token, t.content->'nested_5') from json_each(json_col) as t(token, content)))
)  as foo(key, val)) as json_col
from my_table

这是可行的,但给出了相反的结果(符合逻辑,基于上述查询):

{
   "nested_3": {
      "title": "This is nested key 3",
      "description": "This is nested key 3",
      "meta": "This is nested key 3"
   },
   "nested_5": {
      "title": "This is nested key 5",
      "description": "This is nested key 5",
      "meta": "This is nested key 5"
   }
}

我也试过嵌套:

(select json_object_agg(t.token, json_object_agg(t.content->'nested_3', t.languages->'nested_5')) from json_each(json_col) as t(token, content))

但这给了我一个错误:aggregate function calls cannot be nested

有一种方法可以 select 仅特定的嵌套键但保留 json 结构吗?

Postgres 版本:12

找到了一种方法:使用 json_build_object

那么在每个循环中 json_each 中发生的事情我们只需要 keys/value 创建新对象,并且在使用 json_object_agg 将其推送到我们的输出后如果密钥已经存在将推送到以前的对象,否则将创建新密钥。

select 
id,
(
   select 
   json_object_agg(t.token, json_build_object('nested_3', t.content->'nested_3', 'nested_5', t.content->'nested_5'))
   from json_each(json_col) as t(token, content)
) as json_col
from my_table

如果有人有更好的解决方案或者更好的描述解释,请post您的回答。

使用声明的而不是硬编码的键列表,in ('nested_3', 'nested_5')

select id, (
 select jsonb_object_agg(key, (
    select jsonb_object_agg(key, value) 
    from jsonb_each(t.value) 
    where key in ('nested_3', 'nested_5')
 )) json_filtered
 from jsonb_each(jsonfield) t
) from the_table;

SQL Fiddle