【问题标题】:How to get only the jsonb of specific keys from postgres?如何仅从 postgres 获取特定键的 jsonb?
【发布时间】:2018-03-11 17:09:33
【问题描述】:

我知道您可以使用类似这样的方法从 postgres 中的 jsonb 中删除密钥

select '{"a": 1, "b": 2, "c":3}'::jsonb -'a';
 ?column?
----------
{"b": 2 "c":3}
(1 row)

有没有办法只抓取特定的键?就像假设我只想获取 'a' 键的键值对。

这样的?

select '{"a": 1, "b": 2}'::jsonb + 'a' + 'b';
 ?column?
----------
{"a": 1, "b": 2}
(1 row)

编辑:将示例更改为表明我想从 jsonb 中获取多个键值对,而不仅仅是一对。

【问题讨论】:

    标签: postgresql jsonb


    【解决方案1】:
    Begin;
        CREATE TEMPORARY TABLE test (id  serial, jdoc jsonb);
        insert into test(jdoc) values('{"a": {"b":"foo"}}');
        insert into test(jdoc) values('{"a": "test"}');
        insert into test(jdoc) values('{"a":[2,3,4]}');
        insert into test(jdoc) values('{"b":[2,3,4]}');
      commit;
    

    select (jdoc->'a') from test where jdoc ? 'a'
    将获得所有特定键的值。
    如果你想要特定key的JSONB:select jdoc from test where jdoc ? 'a'

    【讨论】:

      【解决方案2】:

      解释情况

      我们有一个 jsonb 值和多个键,ac

      select '{"a": 1, "b": 2, "c":3}'::jsonb - '{a,c}'::text[];
      

      - 是一个整洁的运算符,但给我们的却是你想要的相反

      {"b": 2}
      

      解决方案是将其包装在 array(select jsonb_object_keys(...)) 中并再次执行 -

      select '{"a": 1, "b": 2, "c":3}'::jsonb - array(select jsonb_object_keys('{"a": 1, "b": 2, "c":3}'::jsonb - '{a,c}'::text[]));
      

      你会得到一个 json 只有这些键,ac

      {"a": 1, "c": 3}
      

      【讨论】:

        【解决方案3】:

        你可以这样做

        SELECT jsonb_column->>'key_name_here' as 'column_name_of_your_own' from table_name
        

        在上述查询的情况下,它将是

        select '{"a": 1, "b": 2, "c":3}'::jsonb->>'a'
        

        【讨论】:

          【解决方案4】:

          如果你想用 JSONB 文档过滤多行:

          -- Let's generate rows with JSONB column:
          WITH s AS (SELECT generate_series(1, 100) num),
          g AS (SELECT num, jsonb_build_object('a', s.num, 'b', s.num * 2) obj FROM s),
          
          -- A "filter" adding (in my example only keys of "filter" document remain in result rows)
          j AS (SELECT '{"a": "int", "c": "string"}'::jsonb AS filter),
          a AS (SELECT (ARRAY(SELECT jsonb_object_keys(filter))) AS ar FROM j),
          
          -- Useless keys removing
          o AS (SELECT jsonb_object_agg(l.key, l.value) obj
                  FROM g, LATERAL jsonb_each(g.obj) l, a 
                  WHERE l.key = ANY(a.ar)
                  GROUP BY num)
          
          SELECT * FROM o ORDER BY obj->'a';
          

          【讨论】:

            【解决方案5】:

            我实际上发现这种方式有效。

            select jsonb_build_object('key', column->'key') from table;
            

            参考: https://www.reddit.com/r/PostgreSQL/comments/73auce/new_user_to_postgres_can_i_grab_multiple_keys_of/

            【讨论】:

            • 重要的一点是,您可以在此处拥有多个键,如下所示:jsonb_build_object('a', column->'a', 'b', column->'b')
            【解决方案6】:

            您可以像这样相当容易地过滤到单个键:

            jsonb_object(ARRAY[key, jsonb_data -> key])
            

            ...或者您可以过滤到多个键:

            (SELECT jsonb_object_agg(key, value) FROM jsonb_each(jsonb_data) WHERE key IN ('a', 'b'))
            

            或者在更复杂的条件下,如果你愿意的话:

            (
              SELECT jsonb_object_agg(key, value)
              FROM jsonb_each(jsonb_data)
              WHERE
                key NOT LIKE '__%'
                AND jsonb_typeof(value) != 'null'
            )
            

            这些问题只需阅读documentation即可轻松回答。

            【讨论】:

            • 你知道如何从特定表中抓取jsonb吗?比如column from table?
            • 是的,这些只是您可以在返回的列中使用的示例表达式。
            • 例如SELECT jsonb_object(ARRAY['a', jsonb_data -> 'a']) FROM table;
            【解决方案7】:

            你可以像这样得到值:

             select '{"a": 1, "b": 2}'::jsonb-> 'a';
            

            如果必须,您可以手动将其转换回 jsonb,或者通过数组、hstore 或其他中间类型。这是“手动”方式

             select ('{ "a": '||('{"a": 1, "b": 2}'::jsonb->'a')::text||'}')::jsonb
            

            【讨论】:

            • 确实有效,有没有办法获取多个键而无需将其存储在新的选择变量中?喜欢只是让它成为一个新的 jsonb?
            • 你不应该像这样重建 json/jsonb 对象。有可用的函数in the documentation 来做你想做的事情,即jsonb_object()
            猜你喜欢
            • 1970-01-01
            • 2019-01-23
            • 1970-01-01
            • 2020-09-16
            • 2023-02-01
            • 2018-08-02
            • 2022-11-03
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多