【问题标题】:Efficiently querying JSON with nested arrays in Postgres在 Postgres 中使用嵌套数组有效地查询 JSON
【发布时间】:2017-11-12 03:14:21
【问题描述】:

我正在尝试在 Postgres(Amazon RDS 上的 9.6)中查询 JSON 数据结构。数据包含对象数组,而对象数组又具有包含对象数组的元素。我想在其中一个嵌套数组中找到与键 + 值匹配的所有记录。

给定这样的行:

{"drinkers" : [
  {"name" : "geoff", 
   "beers" : [
     {"name": "PBR"},
     {"name" : "Bud Select"}
    ]}, 
  {"name" : "tom", 
   "beers" : [
     {"name": "Bud Light"},
     {"name" : "Busch"}
    ]}
]}

我想查找名称为“PBR”的drinkers.beers 对象的所有行。我最接近的是:

select jsonb_data 
from bars 
where jsonb_array_elements(jsonb_array_elements(data -> 'drinkers') -> 'beers') ->> 'name' = 'PBR'``

但这不起作用,因为 where 返回一个列表而不是单个真/假来匹配。我已经使用子查询、横向连接等提出了其他解决方案,但所有这些解决方案都存在性能问题,即使使用适当的 gin 索引也是如此。关于如何在 Postgres 中查询这样的数据结构有什么建议吗?

【问题讨论】:

标签: json postgresql


【解决方案1】:

您是否尝试过使用IN 运算符?

WHERE 'PBR' IN (
  SELECT jsonb_array_elements(jsonb_array_elements(data -> 'drinkers') -> 'beers') ->> 'name'
);

另一种方法是使用 JSONB contain(即@>):

WHERE data -> 'drinkers' @> '[{"beers": [{"name": "PBR"}]}]';

【讨论】:

  • 这就是索引的样子(它对我有用):使用 gin ((data -> 'drinkers') jsonb_path_ops) 在 table_name 上创建索引;
【解决方案2】:

抱歉,这可能只是一个注释,但如果返回名称的语句为您提供了一个列表或数组,您是否可以使用'PBR' = ANY jsonb_array_elements(...

【讨论】:

    猜你喜欢
    • 2017-10-19
    • 2018-05-20
    • 1970-01-01
    • 1970-01-01
    • 2020-04-24
    • 2022-01-02
    • 1970-01-01
    • 2017-04-26
    • 1970-01-01
    相关资源
    最近更新 更多