Postgres jsonb_set - 在大于当前数组的索引处添加数组元素
Postgres jsonb_set - add array element at index larger than current array
我正在尝试向 Postgres 中的 jsonb 数组添加元素。
事先我确定每个元素会有什么索引,但我不知道:
- 我添加元素的顺序是什么
- 元素总数是多少
例如,如果最终数组是 [0,1,2,3,4]
(为简单起见,值对应于索引)元素可以按 0,1,3,2,4
或 4,3,2,1,0
等顺序添加 - 它是随机的,我只是等待元素通过并添加它们 - 我不知道会有多少提前。
所以我想做的是将每个元素添加到它的特定索引处,但是我 运行 在使用 json_set
时遇到了问题
要在特定索引处设置元素,我使用以下内容:
SELECT jsonb_set('[0,1,2]', '{0}', '3', true)
returns [3,1,2]
所以这种情况很好 - 但是当我想在超出当前数组范围的索引处设置一个元素时,而不是在数组中创建空 spaces,它只是附加元素到最后,在新创建的索引中。
所以这可行(将元素@索引 3 添加到长度为 3 的数组)
SELECT jsonb_set('[0,1,2]', '{3}', '3', true)
returns [0,1,2,3]
但这不会(将元素@索引 5 添加到长度为 3 的数组)
SELECT jsonb_set('[0,1,2]', '{5}', '5', true)
returns [0,1,2,5]
我希望它是 [0,1,2,undefined,undefined,5]
有没有办法让它工作?我真的不介意空 space 值是什么,可以是 undefined
、null
或一些占位符值。我只想能够在任何索引处插入元素并让 Postgres 为我创建一个新的更大的数组。
行为在 the documentation 中解释(页面末尾的注释之一):
[...] If the item is out of the range -array_length .. array_length -1, and create_missing is true, the new value is added at the beginning of the array if the item is negative, and at the end of the array if it is positive.
创建您自己的函数:
create or replace function jsonb_set_element(jsonb, int, jsonb)
returns jsonb language plpgsql as $$
begin
while jsonb_array_length() < loop
:= || '[null]'::jsonb;
end loop;
return jsonb_set(, array[::text], , true);
end $$;
正在运行的函数:
select
jsonb_set_element('[0,1,2]', 0, '9') as test_0,
jsonb_set_element('[0,1,2]', 3, '3') as test_3,
jsonb_set_element('[0,1,2]', 5, '5') as test_5
test_0 | test_3 | test_5
-----------+--------------+--------------------------
[9, 1, 2] | [0, 1, 2, 3] | [0, 1, 2, null, null, 5]
(1 row)
我正在尝试向 Postgres 中的 jsonb 数组添加元素。
事先我确定每个元素会有什么索引,但我不知道:
- 我添加元素的顺序是什么
- 元素总数是多少
例如,如果最终数组是 [0,1,2,3,4]
(为简单起见,值对应于索引)元素可以按 0,1,3,2,4
或 4,3,2,1,0
等顺序添加 - 它是随机的,我只是等待元素通过并添加它们 - 我不知道会有多少提前。
所以我想做的是将每个元素添加到它的特定索引处,但是我 运行 在使用 json_set
要在特定索引处设置元素,我使用以下内容:
SELECT jsonb_set('[0,1,2]', '{0}', '3', true)
returns [3,1,2]
所以这种情况很好 - 但是当我想在超出当前数组范围的索引处设置一个元素时,而不是在数组中创建空 spaces,它只是附加元素到最后,在新创建的索引中。
所以这可行(将元素@索引 3 添加到长度为 3 的数组)
SELECT jsonb_set('[0,1,2]', '{3}', '3', true)
returns [0,1,2,3]
但这不会(将元素@索引 5 添加到长度为 3 的数组)
SELECT jsonb_set('[0,1,2]', '{5}', '5', true)
returns [0,1,2,5]
我希望它是 [0,1,2,undefined,undefined,5]
有没有办法让它工作?我真的不介意空 space 值是什么,可以是 undefined
、null
或一些占位符值。我只想能够在任何索引处插入元素并让 Postgres 为我创建一个新的更大的数组。
行为在 the documentation 中解释(页面末尾的注释之一):
[...] If the item is out of the range -array_length .. array_length -1, and create_missing is true, the new value is added at the beginning of the array if the item is negative, and at the end of the array if it is positive.
创建您自己的函数:
create or replace function jsonb_set_element(jsonb, int, jsonb)
returns jsonb language plpgsql as $$
begin
while jsonb_array_length() < loop
:= || '[null]'::jsonb;
end loop;
return jsonb_set(, array[::text], , true);
end $$;
正在运行的函数:
select
jsonb_set_element('[0,1,2]', 0, '9') as test_0,
jsonb_set_element('[0,1,2]', 3, '3') as test_3,
jsonb_set_element('[0,1,2]', 5, '5') as test_5
test_0 | test_3 | test_5
-----------+--------------+--------------------------
[9, 1, 2] | [0, 1, 2, 3] | [0, 1, 2, null, null, 5]
(1 row)