2017-04-12 33 views
0

mycolumn是jsonb類型與空陣列的默認值。的毗連目的是數組,如果對象不離開

我想更新這個數組,如果新的值不存在。

選擇查詢:

SELECT mycolumn FROM mytable WHERE id = 1; 

回報:[]

更新查詢:

UPDATE mytable SET mycolumn = mycolumn || '[{"foo":"bar"}]' WHERE id = 1; 

選擇回報:[{"foo":"bar"}]

如果更新查詢運行超過一次,它會將值附加到數組中。

運行更新再次,選擇返回[{"foo":"bar"},{"foo":"bar"}]

是否有更新mycolumn數組值的冪等方法?

+0

應該發生什麼,如果'mycolumn'已經擁有多個數組元素?是否應該在所有元素中替換一個解決方案,即在第一個中,還是在第一個中已經擁有這樣的密鑰? – pozs

+0

@pozs在我的使用情況下,數組應該只有唯一的對象,並沒有重複。如果更新發生在要插入的新對象退出到數組中,則不會發生任何事情。換句話說,更新應該是疊加的,因爲該對象不存在於數組中,否則noop。 – todgru

+0

所以,也不會「更新」(修改)在陣列中的現有對象在任何可能的情況下?你想找到一種方法來添加對象,如果它不存在,然後什麼都不做?如果對象「部分」存在,會發生什麼?即原始值:'[{「a」:「b」,「c」:「d」},{「e」:「f」}]'並且您想要「插入」f.ex. '{ 「一」: 「B」}'? - 或 來回:'[{「a」:「b」},{「e」:「f」}]'和'{「a」:「b」,「c」:「d」} '? – pozs

回答

1

如果「部分」遏制是假表,那麼遏制運營商(<@@>)沒有對你有好處。你需要檢查每一個元素平等:

with append(a) as (
    values (jsonb '{"foo":"bar"}') 
) 
update mytable 
set mycolumn = mycolumn || a 
from append 
where id = 1 
and not exists(
    select 1 
    from jsonb_array_elements(mycolumn) e 
    where e = a 
) 

:你可避免熱膨脹係數(在WITH條款),如果你願意重複要「插入」 JSON對象。

http://rextester.com/IAHE54266

1

使用<@@>運營商諮詢是否是值已經存在數組中:

UPDATE mytable 
SET mycolumn = mycolumn || '[{"foo":"bar"}]' 
WHERE id = 1 AND NOT '[{"foo":"bar"}]'::jsonb <@ mycolumn; 

注意的正常工作只爲單個值。例如:

select '[{"foo":"bar"},{"foo":"baz"}]'::jsonb <@ '[{"foo":"bar"},{"win":"amp"}]'::jsonb; 

即使它具有常見的{"foo":"bar"}對象也是FALSE。在這種情況下,你建議立即進行刪除分解的陣列和使用DISTINCT再次取景它:

UPDATE mytable 
SET mycolumn = (
    SELECT jsonb_agg(DISTINCT j) 
    FROM jsonb_array_elements(mycolumn || '[{"foo":"bar"},{"win":"amp"}]') AS j); 
0

我想你已經選擇了錯誤的jsonb數據結構。這聽起來像你使用了一個對象數組,而你應該使用一個對象,就像一個字典。

試試這個:

create table mytable (id serial primary key, mycolumn jsonb not null default '{}'); 
insert into mytable values (default); 
update mytable set mycolumn = mycolumn || '{"foo":"bar"}'::jsonb; 
update mytable set mycolumn = mycolumn || '{"foo":"baz"}'::jsonb; 
update mytable set mycolumn = mycolumn || '{"stack":"overflow"}'::jsonb; 
select * from mytable; 
id |    mycolumn    
----+------------------------------------- 
    1 | {"foo": "baz", "stack": "overflow"} 
+0

列類型應該是一個對象數組。具有許多鍵值對的對象將不起作用。 – todgru