【问题标题】:Can JSON support a list of objects that can be queried by SQL?JSON可以支持SQL查询的对象列表吗?
【发布时间】:2021-12-31 16:28:28
【问题描述】:

我正在尝试构造一个 JSON 对象,我想查询出具体的结果,具体来说,我将使用 Postgres 读取 JSON 数据。

JSON 示例:

{
  "ports": [
    {"p1":{"interactions_type":{"num_rds":4,"num_wrts":8},"interactions_dynamics":{"rds_min":1,"rds_max":10}}},
    {"p2":{"interactions_type":{"num_rds":7,"num_wrts":2},"interactions_dynamics":{"rds_min":6,"rds_max":8}}},
    {"p3":{"interactions_type":{"num_rds":14,"num_wrts":6},"interactions_dynamics":{"rds_min":5,"rds_max":50}}}
  ]
}

我想运行的一些查询:

  1. 选择所有端口名称 (p1,p2,p3)
  2. 选择端口数 (3)
  3. 为端口 p2 ("rds_min":6,"rds_max":8) 选择所有 interactions_dynamics
  4. 选择interactions_type -> num_rds >= 7 (p2,p3) 的端口
  5. 选择端口名称,interactions_type -> num_wrtsinteractions_dynamics -> rds_min 其中ineraction_dynamics -> rds_max > 20 ("p3,6,5")

你明白了,类似 SQL 的灵活性。我拥有的 JSON 结构可能无法支持我需要做的事情,或者我不知道如何编写查询。

谁能提出一个更好的方法来构建这个?

【问题讨论】:

  • 你使用的是什么版本的 Postgres?
  • {"p1":{…}} 结构更改为{"id": "p1", …},否则您将很难过。或者使用 {"ports": { "p1":{…}, "p2":{…}, "p3":{…} } } 而不是数组,如果你真的必须的话,但请注意你会失去排序(就像在 SQL 关系中一样)。
  • 为什么要使用 JSON?使用普通的 SQL 表,所有这些都会变得简单得多。
  • “类似 SQL 的灵活性” - 然后不要使用 JSON。

标签: json postgresql


【解决方案1】:

根据你在数据库中使用的版本,你可以使用Postgres document json从JSON中提取数据。

Demo

-- select all the port names (p1,p2,p3)
---------------------------------------

select
  jsonb_object_keys(jp) as "port names"
from 
  test t
  cross join jsonb_array_elements(t.data -> 'ports') jp;
  
-- select the number of ports (3)
---------------------------------
  
select
  jsonb_array_length(t.data -> 'ports') as "number of ports"
from 
  test t;
  
-- select all the interactions_dynamics infor for port p2 ("rds_min":6,"rds_max":8)
-----------------------------------------------------------------------------------

select
  jp -> 'p2' -> 'interactions_dynamics'
from 
  test t
  cross join jsonb_array_elements(t.data -> 'ports') jp
where
  jp ? 'p2';
  
-- select the ports with interactions_type -> num_rds >= 7 (p2,p3)
------------------------------------------------------------------

select
  jpv.key
from 
  test t
  cross join jsonb_array_elements(t.data -> 'ports') jp
  cross join jsonb_each(jp) jpv
where
  (jpv.value -> 'interactions_type' ->> 'num_rds') :: int >= 7;
  
-- select the port name, interactions_type -> num_wrts, interactions_dynamics -> rds_min where ineraction_dynamics -> rds_max > 20 ("p3,6,5")
---------------------------------------------------------------------------------------------------------------------------------------------

select
  jpv.key,
  (jpv.value -> 'interactions_type' ->> 'num_wrts') :: int,
  (jpv.value -> 'interactions_dynamics' ->> 'rds_min') :: int
from 
  test t
  cross join jsonb_array_elements(t.data -> 'ports') jp
  cross join jsonb_each(jp) jpv
where
  (jpv.value -> 'interactions_dynamics' ->> 'rds_max') :: int >= 20;

【讨论】:

    猜你喜欢
    • 2021-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-07
    • 2015-07-03
    • 1970-01-01
    相关资源
    最近更新 更多