2015-05-12 43 views
1

我有一个用JSON编写的分析数据的大数据库。如何在Postgresql中验证JSON有效?

我想筛选出不正确的数据行:

  • 无效JSON(某些行有这样的事情:'{"hello": "world'
  • 一些属性是不是数组,因此将采取'{"products": [1,2,3]}'并离开了'{"products": 1}'

我想要做这样的事情:

select * 
from analytics 
where (is_correct_json(json::json)) 
and (is_array(json::json->>'products')) 

我该如何做到这一点?

+4

时,如果列被定义为'json'或'jsonb'不能存储无效JSON。 –

+0

我仍然得到:错误:类型JSON的无效输入语法 细节:输入字符串意外结束。其中:JSON数据第1行:[{“product_id”:1,“color” –

+0

您是对的 - 列是VARCHAR类型,但是我将它转换为JSON。 –

回答

6

这又是一个很好的例子,后来为什么选择从一开始就适当的数据类型正确帮助;)

没有内置函数来检查一个给定的文本是有效的JSON。但是你可以自己写:

create or replace function is_valid_json(p_json text) 
    returns boolean 
as 
$$ 
begin 
    return (p_json::json is not null); 
exception 
    when others then 
    return false; 
end; 
$$ 
language plpgsql 
immutable; 

注意:由于异常处理,这不会很快。如果你在很多无效值上调用这个值,这将大大减慢你的选择。

然而,'{"products": 1}''{"products": [1,2,3]}'都是有效的JSON文档。前者无效的事实基于您的应用程序逻辑,而不是JSON语法。

要验证你需要一个类似的功能,即捕获错误调用json_array_length()

create or replace function is_valid_json_array(p_json text, p_element text) 
    returns boolean 
as 
$$ 
begin 
    return json_array_length(p_json::json -> p_element) >= 0; 
exception 
    when others then 
    return false; 
end; 
$$ 
language plpgsql 
immutable; 
+0

谢谢 - 这是完美的例子,但这是遗留数据库,现在转换它将是一个大问题:) –