【问题标题】:Appending (pushing) and removing from a JSON array in PostgreSQL 9.2, 9.3, and 9.4?在 PostgreSQL 9.2、9.3 和 9.4 中追加(推送)和删除 JSON 数组?
【发布时间】:2015-08-22 19:42:46
【问题描述】:

For versions greater than 9.5 see this question

我已经使用这个在 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);

现在我想要的是

  • addappend_to_json_array 这样的东西接受实际的 jsondata,它是一个 json-array 和我必须添加到该 jsondata 数组的 newString,这个函数应该返回更新了 json 数组。

    UPDATE jsontesting
    SET jsondata=append_to_json_array(jsondata, 'newString')
    WHERE id = 7;
    
  • 删除从 json 数据数组中的一个值,一个用于删除该值的函数。

我尝试搜索 postgreSQL 的文档,但没有找到任何内容。

【问题讨论】:

  • "我不想为此创建多行" - 为什么不呢?这似乎是执行此操作的自然方式,标准化您的数据。仅仅因为 Postgres 提供 NoSQL/非关系数据类型并不意味着它们必须用于所有事情。我在您的示例中看不到任何需要将此值列表反规范化为一个 JSON 文档的内容。
  • 你想如何删除值,按索引还是按值?

标签: arrays json postgresql postgresql-9.4 jsonb


【解决方案1】:

Radek 的想法可以用来定义这些方便的函数:

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"]

如果它们证明对您有用,请欣赏 Radek 的回答。不过,我必须补充一点,我完全同意 a_horse 的评论。

【讨论】:

  • 也许值得遵循 pg 约定并在函数前面加上 jsonb 前缀,因为它们使用 jsonb 数据类型。
【解决方案2】:

添加:

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;

【讨论】:

  • 'newString'::text - 这可能应该被强制转换。
猜你喜欢
  • 2017-07-03
  • 2015-05-01
  • 1970-01-01
  • 2016-04-05
  • 2016-01-06
  • 1970-01-01
  • 1970-01-01
  • 2013-11-23
  • 2018-12-28
相关资源
最近更新 更多