【问题标题】:Remove element from jsonb array从 jsonb 数组中删除元素
【发布时间】:2019-03-05 10:02:57
【问题描述】:

我有以下 jsonb。从数组页面中,我想删除名为“pageb”的元素。类似问题中提供的解决方案对我不起作用。

'{
  "data": {
    "id": "a1aldjfg3f",
    "pages": [
      {
        "type": "pagea"
      },
      {
        "type": "pageb"
      }                                
    ],
    "activity": "test"
  }
}'

我的脚本现在看起来像这样。它不会返回任何错误,但不会删除元素。

  UPDATE database
  SET reports = jsonb_set(reports, '{data,pages}', (reports->'data'->'pages') - ('{"type":"pageb"}'), true)
  WHERE reports->'data'->'pages'  @> '[{"type":"pageb"}]';

【问题讨论】:

标签: postgresql jsonb


【解决方案1】:

- 运算符不能在这里应用,因为右边的操作数是一个定义键的字符串,per the documentation:

从左操作数中删除键/值对或字符串元素。键/值对根据其键值进行匹配。

从 json 数组中删除 json 对象可以通过解包数组并找到对象的索引来完成。使用这种方法的查询可能过于复杂,因此在这种情况下定义自定义函数非常方便。

create or replace function jsonb_remove_array_element(arr jsonb, element jsonb)
returns jsonb language sql immutable as $$
    select arr- (
        select ordinality- 1
        from jsonb_array_elements(arr) with ordinality
        where value = element)::int
$$;

还有更新:

update my_table
set reports = 
    jsonb_set(
        reports, 
        '{data,pages}', 
        jsonb_remove_array_element(reports->'data'->'pages', '{"type":"pageb"}')
        )
where reports->'data'->'pages'  @> '[{"type":"pageb"}]';

Working example in rextester.

【讨论】:

    【解决方案2】:

    以下是 answer provided 的组合,用于可靠地删除数组内的元素和 PostgreSQL 使用 data-modifying WITH statements 的能力,但它需要一个标识列(id 在我的test 表中)才能工作因为必要的相关性:

    WITH new_reports AS (
        SELECT
            id,
            reports #- array['data','pages',(position - 1)::text] AS new_value
        FROM
            test,
            jsonb_array_elements(reports->'data'->'pages') WITH ORDINALITY arr(item, position)
        WHERE
            test.reports->'data'->'pages' @> '[{"type":"pageb"}]'
            AND
            item->>'type' = 'pageb'
        )
    UPDATE test SET reports = new_reports.new_value FROM new_reports WHERE test.id = new_reports.id;
    

    我使用的测试数据:

    SELECT reports FROM test;
                                                   reports                                               
    -----------------------------------------------------------------------------------------------------
     {"data": {"id": "a1aldjfg3f", "pages": [{"type": "pagea"}, {"type": "pagec"}], "activity": "test"}}
     {"data": {"id": "a1aldjfg3f", "pages": [{"type": "pagea"}, {"type": "pageb"}], "activity": "test"}}
     {"data": {"id": "a1aldjfg3f", "pages": [{"type": "pageb"}, {"type": "pagec"}], "activity": "test"}}
    (3 rows)
    

    ...执行查询后:

    SELECT reports FROM test;
                                                   reports                                               
    -----------------------------------------------------------------------------------------------------
     {"data": {"id": "a1aldjfg3f", "pages": [{"type": "pagea"}, {"type": "pagec"}], "activity": "test"}}
     {"data": {"id": "a1aldjfg3f", "pages": [{"type": "pagea"}], "activity": "test"}}
     {"data": {"id": "a1aldjfg3f", "pages": [{"type": "pagec"}], "activity": "test"}}
    (3 rows)
    

    我希望这对你有用。

    【讨论】:

      【解决方案3】:

      你来了

      do $$
      declare newvar jsonb;
      begin
          newvar := jsonb '{ "customer": "John Doe", "buy": [{"product": "Beer","qty": 6},{"product": "coca","qty": 5}]}';
          newvar := jsonb_set(newvar,'{buy}', jsonb_remove((newvar->>'buy')::jsonb,'{"product": "Beer"}'));
          newvar := jsonb_set(newvar,'{buy}', jsonb_add((newvar->>'buy')::jsonb,'{"product": "cofe","qty": 6}'));
          RAISE NOTICE '%', newvar; 
      end $$
      
      create or replace function jsonb_remove(arr jsonb, element jsonb)
      returns jsonb language sql immutable as $$
          select ('['||coalesce(string_agg(r::text,','),'')||']')::jsonb from jsonb_array_elements(arr) r where r @> element=false
      $$;
      
      create or replace function jsonb_add(arr jsonb, element jsonb)
      returns jsonb language sql immutable as $$
          select arr||element
      $$;
      

      【讨论】:

        猜你喜欢
        • 2015-07-12
        • 2022-05-25
        • 1970-01-01
        • 1970-01-01
        • 2017-03-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-31
        相关资源
        最近更新 更多