2016-05-21 79 views
1

我有一個表如何查詢JSONB數組?

Visitor: (id, .., custom::jsonb[])

custom是形式{field:string, value:string}的JSON對象的數組。例如:

{"field": "apps_created", "value": "3"}

說我想找到所有的Visitors有3個或更多apps_created,我怎麼會去嗎?注意:每個Visitor可以有不同的字段,並且通常不會與其他訪問者重疊。

我試着諮詢Postgres的文件或其他計算器的問題,但我有一個很難搞清楚哪些功能/運營商在這種情況下使用。

任何幫助深表感謝

+0

你可以讓生活即,從每個字典刪除「場」和「值」,從而,而不是與兩個元素的字典你有一個字典,一個:通過存儲{「3」「apps_created」}容易。事實上,如果你這樣做,你也許可以扔的字典的東西全陣列,並有一個大的字典這將是這麼容易與PostgreSQL和在你的代碼 – e4c5

+0

的工作的原因所在,用於存儲這樣的說法是因爲我讓用戶提交自定義數據字段/值,因此無法在設計時知道它們。 AFAIK硬編碼像 – Tarlen

+0

我的建議你還是不需要知道這些字段是在設計時的關鍵時,這是不可能的。 – e4c5

回答

1
select * 
from visitor 
where 
    exists (
    select 1 
    from unnest(custom) t(x) 
    where x->>'field' = 'apps_created' and (x->>'value')::int >= 3); 

UPD
但是在關係數據庫來實現這樣的事情經典的方式是(示意圖):

create table entity (
    entity_id serial not null primary key, 
    ...); 

create table param (
    param_id serial not null primary key, 
    param_name varchar not null unique, 
    ...); 

create table param_value (
    param_id int references param(param_id), 
    entity_id int references entity(entity_id) on delete cascade, 
    value varchar, 
    ... 
    primary key (param_id, entity_id)); 
+0

太棒了,謝謝。你能解釋't(x)'語法嗎?我估計,它映射x到陣列中的每個元素,但一個簡要的闡述,將不勝感激 – Tarlen

+0

此外,關於索引這個查詢,是對領域的GIN索引,然後值的路要走? – Tarlen

+0

@Tarlen 1)它是在從子句,其中't'爲子查詢和可選別名括號字段別名子查詢標準語法:'...從(選擇1爲x)t'或'.. from(select 1)t(x)'。在我們的例子中,「unnest(custom)」等於'(select unnest(custom))'; 2)我從未使用GIN索引。 – Abelisto

相關問題