Добавяне (избутване) и премахване от 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);

Сега това, което исках, беше

  • add Нещо като append_to_json_array приема действителните jsondata, които са json-масив и newString, който трябва да добавя към този 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