使用postgres 9.4将JSON元素附加到数组

时间:2017-02-06 18:25:35

标签: arrays json postgresql groovy postgres-9.4

我正在尝试将JSON元素附加到数据库中已存在的数组中。我知道jsonb_set然而我无法升级到Postgres 9.4,因为这是一个groovy项目,Maven上的最新postgresql版本是9.4。

我目前有一个像这样的json结构:

"playersContainer": {
        "players": [
            {
                "id": "1",
                "name": "Nick Pocock",
                "teamName": "Shire Soldiers",
                "bio" : "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla imperdiet lorem tellus, in bibendum sem dignissim sed. Etiam eu elit sit amet lacus accumsan blandit sed ut dolor. Mauris vel dui non nisi vestibulum commodo vel id magna. Donec egestas magna in tincidunt mollis. Fusce mauris arcu, rhoncus ut lacus sed, fermentum ultrices elit. In sollicitudin at ex dapibus vestibulum. Pellentesque congue, est id lobortis viverra, mauris lectus pharetra orci, ut suscipit nisl purus vehicula est. Aliquam suscipit non velit vel feugiat. Quisque nec dictum augue.",
                "ratings": [
                    1,
                    5,
                    6,
                    9
                ],
                "assists": 17,
                "manOfTheMatches": 20,
                "cleanSheets": 1,
                "data": [
                    3,
                    2,
                    3,
                    5,
                    6
                ],
                "totalGoals": 19

            }
}

我想将新播放器添加到播放器阵列并更新我的数据库,我尝试进行更新,但它擦除了其余的数据。有没有办法定位玩家数组并将新的json对象附加到它?

1 个答案:

答案 0 :(得分:0)

不幸的是9.4没有json_set函数。你可以使用这样的东西:

WITH old_players AS (
       SELECT $1 AS j
  ), new_player AS (
       SELECT $2 AS j
  ), all_players AS (
       SELECT json_array_elements(j->'playersContainer'->'players') AS p
         FROM old_players
        UNION ALL
       SELECT *
         FROM new_player
  )      SELECT ('{"playersContainer": {"players": ' || json_agg(p) || '}}')::json
    FROM all_players
;

您可以将其用作功能:

CREATE OR REPLACE FUNCTION add_player(old_player json, new_player json) RETURNS json AS $$
WITH all_players AS (
       SELECT json_array_elements(($1)->'playersContainer'->'players') AS p
        UNION ALL
       SELECT $2
  ) 
  SELECT ('{"playersContainer": {"players": ' || json_agg(p) || '}}')::json
    FROM all_players
$$ LANGUAGE sql IMMUTABLE;

之后你可以打电话给它:

UPDATE site_content SET content = add_player(content, '{"id": "2",  "name": "Someone Else"}') where id = :id;