如何更新 json 类型的 json 中的任何字段?它应该接受一个对象或一个键数组,如果它存在则更新键,否则创建
Posted
技术标签:
【中文标题】如何更新 json 类型的 json 中的任何字段?它应该接受一个对象或一个键数组,如果它存在则更新键,否则创建【英文标题】:How to update any field in a json of type json? It should accept an object or an array of key(s) and update the key if it exists else create 【发布时间】:2021-12-12 10:57:56 【问题描述】:nodejs 和 Postgres 中的通用函数,用于更新 Postgres 中 JSON 类型的 JSON 列中的键。
我尝试了以下查询:
update contacts set contact_data = jsonb_set(contact_data, 'order_id', '$order_date', '$product_name') where id = $id;
但问题是每次我需要指定键时。我需要一些通用的东西,接受一组键并更新它们的东西。每次调用函数时,键可能会有所不同。
我试图避免循环,因为每次触发更新时,Postgres 都会重写整行,或者至少这是我所知道的。
如果您需要有关该问题的更多说明,请告诉我。 谢谢。
【问题讨论】:
那句话有什么不一般的地方? 每次需要更新一个新的key,都需要在查询中添加,这会导致函数和查询的修改。我想避免这种情况。 为键使用参数。 如果您需要经常这样做,这很好地表明通过引入 JSON 来反规范化您的模型并不是一个好主意。 是的,但是如果我们要更新多个键呢?键(及其编号)可能会有所不同。 【参考方案1】:此解决方案将 jsonb 数据转换为文本,以便与 jsonb 数据结构无关:
你向函数jsonb_key_replace
传递了一个old_keys 数组,该数组将被一个new_keys 数组替换。函数 jsonb_key_replace 迭代聚合函数 replace_agg 并将结果转换为 jsonb :
CREATE OR REPLACE FUNCTION replace(str1 text, str2 text, old text, new text)
RETURNS text LANGUAGE sql IMMUTABLE AS
$$
SELECT replace(COALESCE(str1,str2), old, new) ;
$$ ;
DROP AGGREGATE IF EXISTS replace_agg (text, text, text) ;
CREATE AGGREGATE replace_agg (text, text, text)
( sfunc = replace
, stype = text
) ;
CREATE OR REPLACE FUNCTION jsonb_key_replace
( jsonb_to_update jsonb
, old_keys text[]
, new_keys text[]
)
RETURNS jsonb LANGUAGE sql IMMUTABLE AS
$$
SELECT replace_agg(jsonb_to_update :: text, '"' || l.old || '":', '"' || l.new || '":') :: jsonb
FROM unnest(old_key, new_key) AS l(old, new) ;
$$ ;
【讨论】:
以上是关于如何更新 json 类型的 json 中的任何字段?它应该接受一个对象或一个键数组,如果它存在则更新键,否则创建的主要内容,如果未能解决你的问题,请参考以下文章
如何从 Spring Boot 更新 mongoDb 中的单个 JSON 字段