检查对象键是否在json对象数组中出现两次

时间:2016-09-26 19:18:27

标签: postgresql jsonb

给定一个如下所示的jsonb数组:

[
  { "type": "foo", "desc": "example" },

  { "type": "foo", "desc": "second example" },

  { "type": "bar", "desc": "third example" }
]

我想创建一个postgresql函数,如果{ "type": "foo" }出现两次,则返回true。

2 个答案:

答案 0 :(得分: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) 

答案 1 :(得分: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遍历jsonb_array_elements数组的元素,并计算type等于foo的元素。