我有一个ActiveRecord模型,我们将其命名为API::Response
,其中有一个名为error_messages
的列,该列存储API调用失败时的错误消息。
API::Response
的结构类似于:
#<API::Response:0x0000000019579298
id: "fffefdae43c0",
api_id: "11c91374f10e",
parent_id: nil,
code: "ABC123",
meta_field: "{}",
lock_version: 1,
created_at: Thu, 01 Feb 2019 15:28:37 UTC +00:00,
updated_at: Tue, 09 Oct 2019 20:32:03 UTC +00:00,
version: 1538352000,
error_messages: {"api_failure_1"=> "API failure reason 1", "api_failure_2"=> "API failure reason 2"},
output_data: { "foo" => "bar"},
override_applied: false>
我想要做的是获得一个结果,该结果是我在keys
列中按error_messages
进行分组,并获取每个键的出现次数:
像这样的东西
key | count
-----------------------------
api_failure_1 | 1
api_failure_2 | 3
some_other_failure | n
...
其中keys
jsonb字段中的error_messages
是动态的。
我试图做类似的事情
API::Response.where.not("error_messages = '{}'").group("error_messages").count
但这只是给我每个不同的error_messages
=> {
{"api_failure_1"=> "API failure 1",
"api_failure_2"=> "API failure 2"}=>1,
{"api_failure_1"=> "API failure 1",
"api_failure_3"=> "API failure 3"}=>1
}
而不是其中每个键的计数。
我正在使用Rails 5.2和PostgreSQL 10.4
非常感谢任何指针或帮助。
答案 0 :(得分:3)
事实上,您能够使它工作!进行以下查询:
query = <<-SQL
select errors.types, COUNT(errors.types)
from (select jsonb_object_keys(error_messages) as types from api_responses) errors
group by errors.types
SQL
your_result = API::Response.find_by_sql(query)
我仍然建议您创建一个视图,这样可以更轻松地访问它。
答案 1 :(得分:0)
我认为PostgreSQL无法对jsonb字段中的键进行分组。我认为您需要采取的方法:查询所有带有错误的响应,然后对所有找到的记录使用循环,以使用常规Ruby代码进行分组。
# not tested, but something like:
errors = API::Response.where.not("error_messages = '{}'").pluck(:error_messages)
error_holder = []
errors.each do |error|
error_holder << error.keys
end
counts = Hash.new(0)
error_holder.flatten.each { |name| counts[name] += 1 }
puts counts