如何分组/选择JSON类型列(PG :: UndefinedFunction:ERROR:无法识别json类型的相等运算符)

时间:2014-06-24 01:47:17

标签: postgresql ruby-on-rails-4 rails-activerecord

我想做

<MODEL>.select("brief_content").group("brief_content")

这是表格方案,

                :id => :integer,
           :content => :json,
     :brief_content => :json

但我得到了错误,

我该怎么办,谢谢

companyAlarmLog Load (0.9ms)  SELECT company_alarm_logs.id, company_alarm_logs.name, company_alarm_logs.utc_time, company_alarm_logs.company_alarm_test_id, company_alarm_logs.brief_content, brief_content FROM "company_alarm_logs" GROUP BY brief_content ORDER BY utc_time
E, [2014-06-24T09:40:39.069988 #954] ERROR -- : PG::UndefinedFunction: ERROR:  could not identify an equality operator for type json
LINE 1: ...t, brief_content FROM "company_alarm_logs"  GROUP BY brief_cont...
                                                             ^
: SELECT company_alarm_logs.id, company_alarm_logs.name, company_alarm_logs.utc_time, company_alarm_logs.company_alarm_test_id, company_alarm_logs.brief_content, brief_content FROM "company_alarm_logs"  GROUP BY brief_content  ORDER BY utc_time
Hirb Error: PG::UndefinedFunction: ERROR:  could not identify an equality operator for type json
LINE 1: ...t, brief_content FROM "company_alarm_logs"  GROUP BY brief_cont...

2 个答案:

答案 0 :(得分:9)

不幸的是,在9.3中没有直接json平等测试的简单方法。

9.3&#39; json类型没有相等运算符,因为它接受带有重复键的json(正如许多实现所期望的那样)。如果{"a":1, "a":2}是&#34;等于&#34;则不清楚到{"a":1}或不。{/ p>

9.4添加jsonb,在最后一键获胜的基础上折叠重复键,使得相等无误。

regress=# SELECT '{"a":1, "a":2}'::json = '{"a":1}'::json;
ERROR:  operator does not exist: json = json
LINE 1: SELECT '{"a":1, "a":2}'::json = '{"a":1}'::json;
                                      ^
HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.

regress=# SELECT '{"a":1, "a":2}'::jsonb = '{"a":1}'::jsonb;
 ?column? 
----------
 f
(1 row)

不幸的是,这意味着你无法在9.3中完成你想做的事。

您可以为json编写一个自定义相等运算符 - 也许只是将两者都转换为文本并进行比较,但这会将{"a":1, "b":2}{"b":2, "a":1}视为不相等。< / p>

更好的选择是安装PL / V8并使用V8 JavaScript引擎的json操作来执行相等比较。

json定义一个等于运算符,然后使用该运算符定义一个简单的b-tree opclass。两者在SQL级别都很简单 - 请参阅CREATE OPERATORCREATE OPERATOR CLASS

一旦完成,您将能够在9.3中GROUP BY json值。

或者您可以安装9.4 beta1并使用jsonb

答案 1 :(得分:1)

.group('brief_content:text')应该做到这一点。无论如何,当字段在序列化的json中具有不同的顺序时,它可能是不准确的。在rails中这应该不是问题。