如果存储在 json 字段中,postgres 如何在数组中添加值

postgres how to add value inside array if store in json field

{
    "title": "new abc",
    "genres": ["Fiction", "Thriller", "Horror"],
    "published": false
}

这是我在数据库中的 JSON 存储。 我想在 genres 字段中添加值,它是数组。

jsonb_insert 可能就是您要找的。

来自文档

jsonb_insert(target jsonb, path text[], new_value jsonb [, insert_after boolean])

Returns target with new_value inserted. If target section designated by path is in a JSONB array, new_value will be inserted before target or after if insert_after is true (default is false). If target section designated by path is in JSONB object, new_value will be inserted only if target does not exist. As with the path oriented operators, negative integers that appear in path count from the end of JSON arrays.

此查询在数组的开头向 genres 数组插入一个名为 Comedy 的新元素 - 在 PostgreSQL 10.10 上测试:

SELECT jsonb_insert('{"title": "new abc",
                      "genres": ["Fiction", "Thriller", "Horror"],
                      "published": false}','{genres,0}','"Comedy"',false);

                                          jsonb_insert                                           
-------------------------------------------------------------------------------------------------
 {"title": "new abc", "genres": ["Comedy", "Fiction", "Thriller", "Horror"], "published": false}
(1 Zeile)

编辑:在插入元素之前检查数组中是否已经存在元素 - 请参阅评论:

示例数据

CREATE TEMPORARY TABLE t (f jsonb);
INSERT INTO t VALUES ('{"title": "new abc",
                      "genres": ["Fiction", "Thriller", "Horror"],
                      "published": false}');

查询 - 不存在的元素

SELECT jsonb_insert(f,'{genres,0}','"Comedy"',false) 
FROM t
WHERE '"Comedy"' NOT IN 
  (SELECT * FROM jsonb_array_elements(f#>'{genres}'));

-------------------------------------------------------------------------------------------------
 {"title": "new abc", "genres": ["Comedy", "Fiction", "Thriller", "Horror"], "published": false}
(1 Zeile)

查询 - 现有元素

SELECT jsonb_insert(f,'{genres,0}','"Fiction"',false) 
FROM t
WHERE '"Fiction"' NOT IN 
  (SELECT * FROM jsonb_array_elements(f#>'{genres}'));

 jsonb_insert 
--------------
(0 Zeilen)