Postgresql 如何跨POSTGE中的所有表行从JSONB数组中删除节点?
我有一个名为“Bookmarks”的表,其中包含几个标准行,还有一个名为“columnsettings”的JSONB列 此JSONB列的内容如下所示Postgresql 如何跨POSTGE中的所有表行从JSONB数组中删除节点?,postgresql,jsonb,Postgresql,Jsonb,我有一个名为“Bookmarks”的表,其中包含几个标准行,还有一个名为“columnsettings”的JSONB列 此JSONB列的内容如下所示 [ { "data": "id", "width": 25 }, { "data": "field_1", "width": 125
[
{
"data": "id",
"width": 25
},
{
"data": "field_1",
"width": 125
},
{
"data": "field_12",
"width": 125
},
{
"data": "field_11",
"width": 125
},
{
"data": "field_2",
"width": 125
},
{
"data": "field_7",
"width": 125
},
{
"data": "field_8",
"width": 125
},
{
"data": "field_9",
"width": 125
},
{
"data": "field_10",
"width": 125
}
]
我正在尝试编写一条update语句,该语句将通过删除我指定的特定节点来更新此columnsettings。例如,我可能希望更新columnsettings,并仅删除data='field_2'所在的节点作为示例
我已经尝试了很多东西…我相信它看起来会像这样,但这是错误的
update public."Bookmarks"
set columnsettings =
jsonb_set(columnsettings, (columnsettings->'data') - 'field_2');
在这样的JSONB数组中删除节点的正确语法是什么
当只有一行时,我确实得到了一个工作的版本。这将正确更新JSONB列并删除节点
UPDATE public."Bookmarks" SET columnsettings = columnsettings - (select position-1 from public."Bookmarks", jsonb_array_elements(columnsettings) with ordinality arr(elem, position) WHERE elem->>'data' = 'field_2')::int
但是,我希望它应用于表中的每一行。当有多行时,我得到错误“作为表达式使用的子查询返回多行”
如何让此查询更新表中的所有行
更新后,提供的答案解决了我的问题 现在我有了另一个JSONB专栏,在这里我需要做同样的过滤。结构有点不同,看起来像这样
{
"filters": [
{
"field": "field_8",
"value": [
1
],
"header": "Colors",
"uitype": 7,
"operator": "searchvalues",
"textvalues": [
"Red"
],
"displayfield": "field_8_options"
}
],
"rowHeight": 1,
"detailViewWidth": 1059
}
我尝试使用以下相同的语法:
UPDATE public."Bookmarks"
SET tabsettings = filtered_elements.tabsettings
FROM (
SELECT bookmarkid, JSONB_AGG(el) as tabsettings
FROM public."Bookmarks",
JSONB_ARRAY_ELEMENTS(tabsettings) AS el
WHERE el->'filters'->>'field' != 'field_8'
GROUP BY bookmarkid
) AS filtered_elements
WHERE filtered_elements.bookmarkid = public."Bookmarks".bookmarkid;
这会产生一个错误:“无法从对象中提取元素”
我想我的语法是正确的,但是这行应该如何格式化呢
WHERE el->'filters'->>'field' != 'field_8'
我也尝试了这种格式来访问数组。这没有给出错误,但它找不到任何匹配项…即使有记录
UPDATE public."Bookmarks"
SET tabsettings = filtered_elements.tabsettings
FROM (
SELECT bookmarkid, JSONB_AGG(el) as tabsettings
FROM public."Bookmarks",
JSONB_ARRAY_ELEMENTS(tabsettings->'filters') AS el
WHERE el->>'field' != 'field_8'
GROUP BY bookmarkid
) AS filtered_elements
WHERE filtered_elements.bookmarkid = public."Bookmarks".bookmarkid;
更新
如果数组中有多个“过滤器”,则此查询现在似乎可以工作。
但是,如果数组中只有一个元素应该被排除,它不会删除该项
UPDATE public."Bookmarks"
SET tabsettings = filtered_elements.tabsettings
FROM (
SELECT bookmarkid,
tabsettings || JSONB_BUILD_OBJECT('filters', JSONB_AGG(el)) as tabsettings
FROM public."Bookmarks",
-- this must be an array
JSONB_ARRAY_ELEMENTS(tabsettings->'filters') AS el
WHERE el->>'field' != 'field_8'
GROUP BY bookmarkid
) AS filtered_elements
WHERE filtered_elements.bookmarkid = public."Bookmarks".bookmarkid;
您可以解构、过滤和重新构造JSONB数组。像这样的方法应该会奏效:
UPDATE bookmarks
SET columnsettings = filtered_elements.columnsettings
FROM (
SELECT id, JSONB_AGG(el) as columnsettings
FROM bookmarks,
JSONB_ARRAY_ELEMENTS(columnsettings) AS el
WHERE el->>'data' != 'field_2'
GROUP BY id
) AS filtered_elements
WHERE filtered_elements.id = bookmarks.id;
使用JSONB\u ARRAY\u元素
,可以将JSONB数组转换为行,每个对象一行,称之为el
。然后,您可以访问数据
属性以过滤掉“field_2”条目。最后,按id
分组,将剩余的最小值放回一起,并更新相应的行
编辑如果数据是对象中的嵌套数组,则:
您可以解构、过滤和重新构造JSONB数组。像这样的方法应该会奏效:
UPDATE bookmarks
SET columnsettings = filtered_elements.columnsettings
FROM (
SELECT id, JSONB_AGG(el) as columnsettings
FROM bookmarks,
JSONB_ARRAY_ELEMENTS(columnsettings) AS el
WHERE el->>'data' != 'field_2'
GROUP BY id
) AS filtered_elements
WHERE filtered_elements.id = bookmarks.id;
使用JSONB\u ARRAY\u元素
,可以将JSONB数组转换为行,每个对象一行,称之为el
。然后,您可以访问数据
属性以过滤掉“field_2”条目。最后,按id
分组,将剩余的最小值放回一起,并更新相应的行
编辑如果数据是对象中的嵌套数组,则:
嘿@Ruben,我用稍微不同的JSONB格式更新了我的问题。你能指出我在这个不同的JSONB格式上执行相同过滤的语法有什么错误吗?Thx,我尝试过这个方法,如果数组中有多个匹配的节点,它似乎可以工作。在这种情况下,它会正确地删除/筛选出节点。但是,如果数组中只有一个节点与我尝试筛选出的节点匹配,它将忽略该节点,并且该项将保留。有没有关于如何修复的想法?我会在一个单独的update语句中过滤掉这些情况<代码>其中JSONB_数组_长度(tabsettings->'filters')=1和tabsettings->'filters'->0->>'field'='field_2'并使用
-
操作符删除键。更多详细信息,请参见Hey@Ruben,我用稍微不同的JSONB格式更新了我的问题。你能指出我在这个不同的JSONB格式上执行相同过滤的语法有什么错误吗?Thx,我尝试过这个方法,如果数组中有多个匹配的节点,它似乎可以工作。在这种情况下,它会正确地删除/筛选出节点。但是,如果数组中只有一个节点与我尝试筛选出的节点匹配,它将忽略该节点,并且该项将保留。有没有关于如何修复的想法?我会在一个单独的update语句中过滤掉这些情况<代码>其中JSONB_数组_长度(tabsettings->'filters')=1和tabsettings->'filters'->0->>'field'='field_2'并使用-
操作符删除键。有关更多详细信息,请参阅