将JSON数组转换为JSON映射

问题描述 投票:0回答:2

我有一个名为datasource的postgresql表,其中jsonb列名为config。它具有以下结构:

{  
   "url":"some_url",
   "password":"some_password",
   "username":"some_username",
   "projectNames":[  
      "project_name_1",
      ...
      "project_name_N"
   ]
}

我想将嵌套的json数组projectNames转换为一个映射,并为数组中的每个元素添加一个默认值,所以它看起来像:

{  
   "url":"some_url",
   "password":"some_password",
   "username":"some_username",
   "projectNames":{  
      "project_name_1": "value",
      ...
      "project_name_N": "value"
   }
}

我使用postgresql jsonb运算符projectNames从表中选择了config#>'{projectNames}',但我不知道如何执行变换操作。

我想,我应该使用类似jsonb_object_agg的东西,但它会将所有数据转换为单行。

我正在使用PostgreSQL 9.6版本。

json postgresql jsonb
2个回答
1
投票

您需要首先取消该阵列,然后从中构建一个新的JSON文档。然后你可以把它放回到列中。

update datasource
  set config = jsonb_set(config, '{projectNames}', t.map)
from (  
  select id, jsonb_object_agg(pn.n, 'value') as map
  from datasource, jsonb_array_elements_text(config -> 'projectNames') as pn (n)
  group by id
) t
where t.id = datasource.id;

以上假设有一个名为id的主要(或至少是唯一的)列。内部选择将数组转换为地图。

在线示例:http://rextester.com/GPP85654


0
投票

你在找smth喜欢:

t=# with c(j) as (values('{
   "url":"some_url",
   "password":"some_password",
   "username":"some_username",
   "projectNames":[
      "project_name_1",
      "project_name_N"
   ]
}
'::jsonb))
, n as (select j,jsonb_array_elements_text(j->'projectNames') a from c)
select jsonb_pretty(jsonb_set(j,'{projectNames}',jsonb_object_agg(a,'value'))) from n group by j
;
            jsonb_pretty
------------------------------------
 {                                 +
     "url": "some_url",            +
     "password": "some_password",  +
     "username": "some_username",  +
     "projectNames": {             +
         "project_name_1": "value",+
         "project_name_N": "value" +
     }                             +
 }
(1 row)

Time: 19.756 ms

若然,请看:

https://www.postgresql.org/docs/current/static/functions-aggregate.html

https://www.postgresql.org/docs/current/static/functions-json.html

© www.soinside.com 2019 - 2024. All rights reserved.