如何仅从 postgres 获取特定键的 jsonb?

Posted

技术标签:

【中文标题】如何仅从 postgres 获取特定键的 jsonb?【英文标题】:How to get only the jsonb of specific keys from postgres? 【发布时间】: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 中获取多个键值对,而不仅仅是一对。

【问题讨论】:

【参考方案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()

以上是关于如何仅从 postgres 获取特定键的 jsonb?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 JSON 键的 postgres 更新语句中增加值

Bigquery:是不是有一种 json 路径方法可以仅从具有动态键的 json 数组中提取值?

如何使用 Node.js 将特定键:Json 的值插入到 postgres 表中

如何仅从 JSON 数据中获取最后 10 个对象

如何仅从系列或列表中获取特定值[关闭]

如何获取数据列表,特定日期仅从每个日期获取 6 条记录而不是更多