Добавление (проталкивание) и удаление из массива JSON в PostgreSQL 9.2, 9.3 и 9.4?

Для версий выше 9.5 см. этот вопрос

Я создал таблицу в PostgreSQL, используя это:

CREATE TEMP TABLE jsontesting
AS
  SELECT id, jsondata::jsonb FROM ( VALUES
    (1, '["abra","value","mango", "apple", "sample"]'),
    (2, '["japan","china","india", "russia", "australia"]'),
    (3, '["must", "match"]'),
    (4, '["abra","value","true", "apple", "sample"]'),
    (5, '["abra","false","mango", "apple", "sample"]'),
    (6, '["string","value","mango", "apple", "sample"]'),
    (7, '["must", "watch"]')
  ) AS t(id,jsondata);

Теперь то, что я хотел, это

  • добавить Что-то вроде append_to_json_array принимает фактические jsondata, которые являются json-массивом, и новую строку, которую я должен добавить в этот массив jsondata, и эта функция должна возвращать обновленный json- множество.

    UPDATE jsontesting
    SET jsondata=append_to_json_array(jsondata, 'newString')
    WHERE id = 7;
    
  • удалить значение из массива данных json, одна функция для удаления значения.

Я попытался найти документацию postgreSQL, но ничего там не нашел.


person govindpatel    schedule 08.06.2015    source источник
comment
Я не хотел создавать для этого несколько строк - почему бы и нет? Кажется, это естественный способ сделать это, нормализовав ваши данные. Тот факт, что Postgres предлагает NoSQL/нереляционные типы данных, не означает, что их нужно использовать везде. Я не вижу в вашем примере ничего, что потребовало бы денормализации этого списка значений в один документ JSON.   -  person a_horse_with_no_name    schedule 08.06.2015
comment
Как вы хотите удалить значение, по индексу или по значению?   -  person Evan Carroll    schedule 14.02.2017


Ответы (2)


Идею Радека можно использовать для определения следующих удобных функций:

create function jsonb_array_append(j jsonb, e text)
returns jsonb language sql immutable
as $$
    select array_to_json(array_append(array(select * from jsonb_array_elements_text(j)), e))::jsonb 
$$;

create function jsonb_array_remove(j jsonb, e text)
returns jsonb language sql immutable
as $$
    select array_to_json(array_remove(array(select * from jsonb_array_elements_text(j)), e))::jsonb 
$$;

create function jsonb_array_replace(j jsonb, e1 text, e2 text)
returns jsonb language sql immutable
as $$
    select array_to_json(array_replace(array(select * from jsonb_array_elements_text(j)), e1, e2))::jsonb 
$$;

Функции в действии:

select jsonb_array_append('["alfa", "beta", "gamma"]', 'delta');
         jsonb_array_append
------------------------------------
 ["alfa", "beta", "gamma", "delta"]

select jsonb_array_remove('["alfa", "beta", "gamma"]', 'beta');
 jsonb_array_remove
-------------------
 ["alfa", "gamma"]

select jsonb_array_replace('["alfa", "beta", "gamma"]', 'alfa', 'delta');
     jsonb_array_replace
----------------------------
 ["delta", "beta", "gamma"]

Если они окажутся полезными для вас, оцените ответ Радека. Однако я должен добавить, что полностью согласен с комментарием a_horse.

person klin    schedule 08.06.2015
comment
Возможно, стоит следовать соглашению pg и добавлять к функциям префикс jsonb, поскольку они используют тип данных jsonb. - person Radek Postołowicz; 09.06.2015

Добавить:

update jsontesting 
set jsondata = array_to_json(array(select * from jsonb_array_elements_text(jsondata)) || 'newString'::text)::jsonb 
where id = 7;

Удалять:

update jsontesting 
set jsondata = array_to_json(array_remove(array(select * from jsonb_array_elements_text(jsondata)), 'toRemove'))::jsonb 
where id = 7;
person Radek Postołowicz    schedule 08.06.2015
comment
'newString'::text - это, вероятно, должно быть брошено. - person klin; 08.06.2015