2016-10-14 223 views
1

我正在使用postgres 9.5.4。Postgres:嵌套jsonb列的範圍查詢

從下面存儲在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 
    } 
    ] 
} 

回答

2
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) 

查詢會因爲unnesting JSON數組與jsonb_array_elements()的必要性,對大型數據集真的很貴。 沒有可用於加速的索引。

+0

非常感謝Klin。這對我有用。正如你所提到的,需要檢查大數據集上的性能。 – Carbonrock

+0

@ klin,在citus集羣上執行此查詢時遇到問題。需要幫忙。 (1)從jsontest,jsonb_array_elements(data - >'o')where(value - >>'mid'):: int> 7000; 錯誤:無法對此查詢執行分佈式計劃 詳細信息:目前不支持複雜表表達式 – Carbonrock

+0

不幸的是,這不是標準的Postgres錯誤消息。似乎citus有其他限制,請參閱[this citus問題](https://github.com/citusdata/citus/issues/521)。 – klin