如何仅从 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 值和多个键,
a
和c
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 只有这些键,a
和 c
"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?的主要内容,如果未能解决你的问题,请参考以下文章
Bigquery:是不是有一种 json 路径方法可以仅从具有动态键的 json 数组中提取值?