按值删除 jsonb 数组元素
Remove jsonb array element by value
我确实弄清楚了如何从数组中删除单个记录的值,但如何为其中的许多记录执行此操作。问题在于我如何使用子查询。因为它必须 return 只有单个元素。可能是我的做法不对。
给定输入:'{attributes:['is_new', 'is_old']}'
预期结果 '{attributes: ['is_old']}' #remove 'is_new' from jsonb array
真实例子:
# 库存 |特性
# ------+--------------------------------
# nu3_1 | { +
# | "name": "silly_hodgkin", +
# | "type": "food", +
# | "attributes":[+
# | "is_gluten_free", +
# | "is_lactose_free", +
# | "is_new" +
# | ] +
# | }
#删除单个数组元素的查询:
SELECT c.sku, jsonb_agg(el) 来自
catalog c JOIN (select sku, jsonb_array_elements_text(properties->'attributes') as el from catalog) c2 ON c.sku=c2.sku 其中 el 'is_new'
分组 c.sku;
#更新删除单个记录中的单个数组元素的查询
更新目录 SET properties=jsonb_set(properties, '{attributes}', (
SELECT jsonb_agg(el) 来自
目录 c JOIN (select sku, jsonb_array_elements_text(properties->'attributes') as el from catalog) c2 ON c.sku=c2.sku
其中 el 'is_new' 和 c.sku='nu3_1'
分组 c.sku
)
) 哪里 sku='nu3_1';
问题又来了。如何根据多个数据库记录的值删除 jsonb 数组元素?
所以,我相信您正在寻找的 QRY 是:
with q as (
select distinct sku, jsonb_set(properties,'{attributes}',jsonb_agg(el) over (partition by sku),false) new_properties
from (
select
sku, jsonb_array_elements_text(properties->'attributes') as el, properties
from catalog
) p
where el != 'is_new'
)
update catalog set properties = q.new_properties from q where catalog.sku = q.sku
;
请注意,我假设您的 sku
至少是 UK
!
您的解决方案有效 + 您向我指出了一些新的东西,例如 window 函数,并为我提供了替代解决方案的想法:
WITH q as (
SELECT c.sku as sku, jsonb_set(properties, '{attributes}', jsonb_agg(el)) as new_properties
FROM catalog c JOIN (select sku, jsonb_array_elements_text(properties->'attributes') as el from catalog) c2 ON c.sku=c2.sku where el != 'is_new'
GROUP BY c.sku
)
UPDATE catalog SET properties=q.new_properties FROM q WHERE catalog.sku=q.sku;
使用jsonb_set()
and the delete operator -
:
update catalog
set properties =
jsonb_set(properties, '{attributes}', (properties->'attributes') - 'is_new');
中测试
json_build_object ( VARIADIC "any" ) → json
jsonb_build_object ( VARIADIC "any" ) → jsonb
Builds a JSON object out of a variadic argument list. By convention,
the argument list consists of alternating keys and values. Key
arguments are coerced to text; value arguments are converted as per
to_json or to_jsonb.
json_build_object('foo', 1, 2, row(3,'bar')) → {"foo" : 1, "2" :
{"f1":3,"f2":"bar"}}
update catalog
set properties = properties - 'attributes' || jsonb_build_object('attributes','[is_gluten_free,is_lactose_free,is_new]')
where properties ? 'attributes'
returning *;
现在您可以替换键,也可以替换值。只需确保 attributes
为顶级键即可。
我确实弄清楚了如何从数组中删除单个记录的值,但如何为其中的许多记录执行此操作。问题在于我如何使用子查询。因为它必须 return 只有单个元素。可能是我的做法不对。
给定输入:'{attributes:['is_new', 'is_old']}' 预期结果 '{attributes: ['is_old']}' #remove 'is_new' from jsonb array
真实例子: # 库存 |特性 # ------+-------------------------------- # nu3_1 | { + # | "name": "silly_hodgkin", + # | "type": "food", + # | "attributes":[+ # | "is_gluten_free", + # | "is_lactose_free", + # | "is_new" + # | ] + # | }
#删除单个数组元素的查询: SELECT c.sku, jsonb_agg(el) 来自 catalog c JOIN (select sku, jsonb_array_elements_text(properties->'attributes') as el from catalog) c2 ON c.sku=c2.sku 其中 el 'is_new' 分组 c.sku;
#更新删除单个记录中的单个数组元素的查询 更新目录 SET properties=jsonb_set(properties, '{attributes}', ( SELECT jsonb_agg(el) 来自 目录 c JOIN (select sku, jsonb_array_elements_text(properties->'attributes') as el from catalog) c2 ON c.sku=c2.sku 其中 el 'is_new' 和 c.sku='nu3_1' 分组 c.sku ) ) 哪里 sku='nu3_1';
问题又来了。如何根据多个数据库记录的值删除 jsonb 数组元素?
所以,我相信您正在寻找的 QRY 是:
with q as (
select distinct sku, jsonb_set(properties,'{attributes}',jsonb_agg(el) over (partition by sku),false) new_properties
from (
select
sku, jsonb_array_elements_text(properties->'attributes') as el, properties
from catalog
) p
where el != 'is_new'
)
update catalog set properties = q.new_properties from q where catalog.sku = q.sku
;
请注意,我假设您的 sku
至少是 UK
!
您的解决方案有效 + 您向我指出了一些新的东西,例如 window 函数,并为我提供了替代解决方案的想法:
WITH q as (
SELECT c.sku as sku, jsonb_set(properties, '{attributes}', jsonb_agg(el)) as new_properties
FROM catalog c JOIN (select sku, jsonb_array_elements_text(properties->'attributes') as el from catalog) c2 ON c.sku=c2.sku where el != 'is_new'
GROUP BY c.sku
)
UPDATE catalog SET properties=q.new_properties FROM q WHERE catalog.sku=q.sku;
使用jsonb_set()
and the delete operator -
:
update catalog
set properties =
jsonb_set(properties, '{attributes}', (properties->'attributes') - 'is_new');
中测试
json_build_object ( VARIADIC "any" ) → json
jsonb_build_object ( VARIADIC "any" ) → jsonb
Builds a JSON object out of a variadic argument list. By convention, the argument list consists of alternating keys and values. Key arguments are coerced to text; value arguments are converted as per to_json or to_jsonb.
json_build_object('foo', 1, 2, row(3,'bar')) → {"foo" : 1, "2" : {"f1":3,"f2":"bar"}}
update catalog
set properties = properties - 'attributes' || jsonb_build_object('attributes','[is_gluten_free,is_lactose_free,is_new]')
where properties ? 'attributes'
returning *;
现在您可以替换键,也可以替换值。只需确保 attributes
为顶级键即可。