查询Postgres 9.3 JSON以检查数组是否包含字符串?

时间:2016-09-08 12:31:20

标签: json postgresql postgresql-9.3

我的JSON列中的一行看起来像这样:

{"general": {
        "somekey": "somevalue", 
        "tags": ["first_tag", "second_tag", "third_tag"]}}

我需要返回包含某些标签的标签列表(例如“first_tag”)。有没有办法在PostgreSQL 9.3中执行此操作?

2 个答案:

答案 0 :(得分:1)

假设该表名为t且该列名为x

SELECT *
FROM t
WHERE exists(
  SELECT 1
  FROM json_array_elements(x#>'{general,tags}')
  WHERE array_to_json(array[value])->>0='first_tag'
);

这不使用jsonb或其他更新的东西,因此它应该适用于9.3。另请参阅sqlfiddle

这个想法是使用json_array_elements函数,它将json数组转换为sql表。该表有一个名为value的{​​{1}}类列。

在这种情况下,我们在子查询中使用json来遍历所有标记的列表。一个复杂因素是json_array_elements(此处表示标记)的类型为value,因此我们必须将其转换为文本。不幸的是,json没有直接执行此操作的功能,因此我们必须将其转换为单个元素数组,然后将该单个元素作为文本提取。然后我们可以将该文本与我们要查找的标记进行比较(在上例中为postgresql)。这一栏的结果并不重要,我们只关心它是否为空。

答案 1 :(得分:0)

您可以使用:

CREATE OR REPLACE FUNCTION fn_json_array_contains(a_json json, a_e anyelement)
RETURNS BOOLEAN AS $BODY$
BEGIN
    RETURN to_json(a_e)::TEXT IN (SELECT value::TEXT FROM json_array_elements(a_json) e);
END;
$BODY$ LANGUAGE plpgsql IMMUTABLE
;

SELECT * FROM t WHERE fn_json_array_contains(x#>'{general,tags}', 'first_tag');