2017-02-16 4 views
0

Учитывая следующее:Postgres/JSON - обновление всех элементов массива

JSON
{ 
    "foo": [ 
    { 
     "bar": true 
    }, 
    { 
     "bar": true 
    } 
    ] 
} 

Как я могу выбрать следующее:

{ 
    "foo": [ 
    { 
     "bar": false 
    }, 
    { 
     "bar": false 
    } 
    ] 
} 

?

До сих пор я понял, как манипулировать одно значение массива:

SELECT 
    jsonb_set(
     '{ 
     "foo": [ 
      { 
      "bar": true 
      }, 
      { 
      "bar": true 
      } 
     ] 
    }'::jsonb, '{foo,0,bar}', to_jsonb(false) 
) 

Но как установить все элементов в массиве?

ответ

1

Нет стандартной функции для обновления элементов массива json по ключу. Пользовательская функция, вероятно, самый простой способ решить эту проблему:

create or replace function update_array_elements(arr jsonb, key text, value jsonb) 
returns jsonb language sql as $$ 
    select jsonb_agg(jsonb_build_object(k, case when k <> key then v else value end)) 
    from jsonb_array_elements(arr) e(e), 
    lateral jsonb_each(e) p(k, v) 
$$; 

select update_array_elements('[{"bar":true},{"bar":true}]'::jsonb, 'bar', 'false'); 

     update_array_elements 
---------------------------------- 
[{"bar": false}, {"bar": false}] 
(1 row) 

Ваш запрос может выглядеть следующим образом:

with a_data(js) as (
values(
    '{ 
     "foo": [ 
      { 
      "bar": true 
      }, 
      { 
      "bar": true 
      } 
     ] 
    }'::jsonb) 
) 
select 
    jsonb_set(js, '{foo}', update_array_elements(js->'foo', 'bar', 'false')) 
    from a_data; 

       jsonb_set     
------------------------------------------- 
{"foo": [{"bar": false}, {"bar": false}]} 
(1 row)  
Смежные вопросы