我们说我们有一张桌子 -
create table test_table(id text not null, data jsonb not null)
我们的价值观为 -
insert into test_table values('data1', '{"name": "Rahul Jain", "emp_id": "73347", "attributes": [{"key": "name", "value": "Amay Adams", "display_name": "Name"}, {"key": "designation", "value": "Senior Software Engineer", "display_name":"Designation"}, {"key": "location", "value": "New Delhi", "display_name": "Location"}, {"key": "dept", "value": "Engineering", "display_name": "Department"}, {"key": "dept", "value": "Engineering", "display_name": "Department"}]}')
现在这个表有数百万条记录。我必须更新密钥dept
的值,即从Engineering
更新为Technology
。我不想使用python脚本来获取值,然后检查密钥然后更新。如何为其进行就地更新,通过某些查询进行更新?外键的更新看似合理,但对于attributes
数组,我找不到任何方法。
答案 0 :(得分:0)
Well, I believe you can do this using plpgsql, but it can be tricky:
=# select jsonb_pretty(data) from test_table;
jsonb_pretty
--------------------------------------------------
{ +
"name": "Rahul Jain", +
"emp_id": "73347", +
"attributes": [ +
{ +
"key": "name", +
"value": "Amay Adams", +
"display_name": "Name" +
}, +
{ +
"key": "designation", +
"value": "Senior Software Engineer",+
"display_name": "Designation" +
}, +
{ +
"key": "location", +
"value": "New Delhi", +
"display_name": "Location" +
}, +
{ +
"key": "dept", +
"value": "Engineering", +
"display_name": "Department" +
}, +
{ +
"key": "dept", +
"value": "Engineering", +
"values": "Engineering", +
"display_name": "Department" +
} +
] +
}
(1 row)
Now perform an update:
DO
$BODY$
DECLARE
record jsonb;
ind int;
path text[];
BEGIN
FOR record IN SELECT data FROM test_table
LOOP
FOR ind in 0..(jsonb_array_length(record->'attributes'))
LOOP
IF record->'attributes'->ind->>'key' = 'dept'
THEN
path = ARRAY['attributes', ind::text, 'value'];
UPDATE test_table
SET data = jsonb_set(data, path, '"Technology"')
WHERE data->>'emp_id' = record->>'emp_id';
END IF;
END LOOP;
END LOOP;
END;
$BODY$ language plpgsql;
And here is the result:
=# select jsonb_pretty(data) from test_table;
jsonb_pretty
--------------------------------------------------
{ +
"name": "Rahul Jain", +
"emp_id": "73347", +
"attributes": [ +
{ +
"key": "name", +
"value": "Amay Adams", +
"display_name": "Name" +
}, +
{ +
"key": "designation", +
"value": "Senior Software Engineer",+
"display_name": "Designation" +
}, +
{ +
"key": "location", +
"value": "New Delhi", +
"display_name": "Location" +
}, +
{ +
"key": "dept", +
"value": "Technology", +
"display_name": "Department" +
}, +
{ +
"key": "dept", +
"value": "Technology", +
"values": "Engineering", +
"display_name": "Department" +
} +
] +
}
(1 row)
Unfortunately, I'm not aware about performance of this solution.