【问题标题】:Postgres: Range Query on nested jsonb columnPostgres:嵌套 jsonb 列上的范围查询
【发布时间】:2017-02-23 18:48:00
【问题描述】:

我正在使用 postgres 9.5.4。

从下面存储在 jsonb 列中的示例 json 数据,我想搜索匹配 o['mid'] > 7000 的记录

这是一个用户记录的样本。将会有数百万这样的用户。

{
  "uid": 14105529,
  "o": [
    {
      "mid": 6551,
      "ac": 1913,
      "ip": "144.36.233.44",
      "adw": 5,
      "at": 133000,
      "ad": 151015,
      "aid": 0
    },
    {
      "mid": 7552,
      "ac": 1913,
      "ip": "144.36.233.44",
      "adw": 5,
      "at": 133000,
      "ad": 151015,
      "aid": 0
    },
    {
      "mid": 7553,
      "ac": 1913,
      "ip": "144.36.233.44",
      "adw": 5,
      "at": 133000,
      "ad": 151015,
      "aid": 0
    }
  ]
}

【问题讨论】:

    标签: json postgresql jsonb


    【解决方案1】:
    with a_table(jdata) as ( 
    values (
        '{
            "uid":14105529,
            "o":[
                {"mid":6551,"ac":1913,"ip":"144.36.233.44","adw":5,"at":133000,"ad":151015,"aid":0}, 
                {"mid":7552,"ac":1913,"ip":"144.36.233.44","adw":5,"at":133000,"ad":151015,"aid":0},
                {"mid":7553,"ac":1913,"ip":"144.36.233.44","adw":5,"at":133000,"ad":151015,"aid":0} 
            ] }'::jsonb
        )
    )
    
    select jdata->'uid' as uid, value
    from a_table, jsonb_array_elements(jdata->'o')
    where (value->>'mid')::int > 7000;
    
       uid    |                                              value                                               
    ----------+--------------------------------------------------------------------------------------------------
     14105529 | {"ac": 1913, "ad": 151015, "at": 133000, "ip": "144.36.233.44", "adw": 5, "aid": 0, "mid": 7552}
     14105529 | {"ac": 1913, "ad": 151015, "at": 133000, "ip": "144.36.233.44", "adw": 5, "aid": 0, "mid": 7553}
    (2 rows)
    

    对于大型数据集,查询将非常昂贵,因为必须使用 jsonb_array_elements() 取消嵌套 json 数组。 没有可以用来加快速度的索引。

    【讨论】:

    • 非常感谢克林。这对我有用。正如您所提到的,需要检查大型数据集的性能。
    • @klin,在 citus 集群上执行此查询时遇到问题。需要帮忙。 postgres=# select count(1) from jsontest, jsonb_array_elements(data->'o') where (value->>'mid')::int>7000;错误:无法对此查询执行分布式计划详细信息:当前不支持复杂的表表达式
    • 不幸的是,这不是标准的 Postgres 错误消息。 citus 似乎有其他限制,请参阅this citus issue
    猜你喜欢
    • 1970-01-01
    • 2017-01-28
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    • 2021-02-18
    • 2023-04-03
    • 2019-03-14
    • 1970-01-01
    相关资源
    最近更新 更多