如何在json列中查询空对象?

时间:2014-06-18 18:23:28

标签: json postgresql types jsonb

查找某个json列包含空对象的所有行{}。这可以使用JSON数组,或者如果我在对象中查找特定键。但我只是想知道对象是否为空。似乎找不到会这样做的运营商。

 dev=# \d test
     Table "public.test"
  Column | Type | Modifiers
 --------+------+-----------
  foo    | json |

 dev=# select * from test;
    foo
 ---------
  {"a":1}
  {"b":1}
  {}
 (3 rows)

 dev=# select * from test where foo != '{}';
 ERROR:  operator does not exist: json <> unknown
 LINE 1: select * from test where foo != '{}';
                                      ^
 HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.
 dev=# select * from test where foo != to_json('{}'::text);
 ERROR:  operator does not exist: json <> json
 LINE 1: select * from test where foo != to_json('{}'::text);
                                      ^
 HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.
 dwv=# select * from test where foo != '{}'::json;
 ERROR:  operator does not exist: json <> json
 LINE 1: select * from test where foo != '{}'::json;
                                      ^
 HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.

6 个答案:

答案 0 :(得分:86)

整个数据类型 json 存在无相等(或不等式)运算符,因为很难建立相等性。在Postgres 9.4或更高版本中考虑jsonb,这是可能的。关于dba.SE(最后一章)的相关答案的更多细节:

SELECT DISTINCT json_column ...... GROUP BY json_column因同样的原因失败(没有相等运算符)。

将表达式的两边都投放到text允许=<>运算符,但这通常不可靠,因为相同有许多可能的文本表示形式> json值。

但是,对于这个特殊情况空对象),它可以正常工作:

select * from test where foo::text <> '{}'::text;

答案 1 :(得分:5)

从PostgreSQL 9.5开始,这种带有JSON数据的查询是不可能的。另一方面,我同意它非常有用,并创建了一个请求:

https://postgresql.uservoice.com/forums/21853-general/suggestions/12305481-check-if-json-is-empty

随意投票,希望它能够实施!

答案 2 :(得分:2)

在9.3中,可以计算每个对象中的对,并过滤没有

的对
create table test (foo json);
insert into test (foo) values
('{"a":1, "c":2}'), ('{"b":1}'), ('{}');

select *
from test
where (select count(*) from json_each(foo) s) = 0;
 foo 
-----
 {}

或测试存在,对于大对象可能更快

select *
from test
where not exists (select 1 from json_each(foo) s);

无论格式化如何,这两种技术都能完美运行

答案 3 :(得分:0)

空JSON数组[]也可能是相关的。

然后这对[]{}都适用:

select * from test where length(foo::text) > 2 ;

答案 4 :(得分:0)

您必须小心。将所有数据强制转换为其他类型,以便您可以进行比较,这将在大型数据库上出现性能问题。

如果数据具有一致的密钥,则可以查找密钥的存在。例如,如果计划数据为{}或{id:'1'}

然后您可以查找没有'id'的项目

SELECT * FROM public."user"
where NOT(plan ? 'id')

答案 5 :(得分:0)

根据JSON Functions and Operators documentation可以使用双箭头函数(->>)来获取一个json对象或者数组字段作为文本。然后对字符串进行相等性检查。

所以这对我有用:

SELECT jsonb_col from my_table
WHERE jsonb_col ->> 'key' = '{}';

或者如果嵌套不止一层,请使用路径函数 (#>>)

SELECT jsonb_col from my_table
WHERE jsonb_col #>> '{key, nestedKey}' = '{}';

截至撰写本文时当前支持的版本:

<块引用>

支持的版本:当前 (13) / 12 / 11 / 10 / 9.6