2016-09-26 23 views

回答

1

使用jsonb_array_elements(),例如:

with data(js) as (
    select 
     '[ 
     { "type": "foo", "desc": "example" }, 
     { "type": "foo", "desc": "second example" }, 
     { "type": "bar", "desc": "third example" } 
     ]'::jsonb 
) 
select elem->>'type' as "type", count(elem->'type') 
from data, jsonb_array_elements(js) elem 
group by 1; 

type | count 
------+------- 
foo |  2 
bar |  1 
(2 rows)  

的功能應該是這樣的:

create or replace function check_duplicates(source jsonb, key text) 
returns boolean language sql as $$ 
    select max(count) > 1 
    from (
     select count(elem->key) 
     from jsonb_array_elements(source) elem 
     group by elem->key 
     ) s 
$$; 

用法:

with data(js) as (
    select 
     '[ 
     { "type": "foo", "desc": "example" }, 
     { "type": "foo", "desc": "second example" }, 
     { "type": "bar", "desc": "third example" } 
     ]'::jsonb 
) 
select check_duplicates(js, 'type') 
from data; 

check_duplicates 
------------------ 
t 
(1 row) 
0

這裏,做一個函數。

CREATE OR REPLACE FUNCTION more_than_two_foos(s jsonb) RETURNS bool AS $$ 
DECLARE 
    c integer; 
BEGIN 
    SELECT count(*) 
    FROM (
     SELECT 1 
     FROM jsonb_array_elements(s) 
     WHERE value->>'type'='foo' 
     LIMIT 2 
    ) t 
    INTO c; 
    RETURN c>=2; 
END; 
$$ LANGUAGE plpgsql IMMUTABLE STRICT; 

下面是一個例子:

$ SELECT more_than_two_foos('[ 
    { "type": "foo", "desc": "example" }, 
    { "type": "foo", "desc": "second example" }, 
    { "type": "bar", "desc": "third example" } 
]'); 
more_than_two_foos 
-------------------- 
t 
(1 row) 

$ SELECT more_than_two_foos('[ 
    { "type": "foo", "desc": "second example" }, 
    { "type": "bar", "desc": "third example" } 
]'); 
more_than_two_foos 
-------------------- 
f 
(1 row) 

的想法是,它通過使用jsonb_array_elementsjsonb數組的元素,並計算有type等於foo的元素。

+0

您是否看到任何方式創建索引以加快對此函數的查詢? –

+0

這只是一個函數,它不會對任何表進行任何查詢,所以它不會受到索引的影響。總的來說,我懷疑是否有一些索引可以用來加快搜索滿足手頭財產的行。 – redneb

相關問題