我想跳过解析我的数据库返回的一些json,当我在padrino应用程序的响应中立即将它再次转回json时。
即我有
get :data, provides: :json do
Record.order(:day).map do |r|
{r.day.to_s => JSON.parse!(r.data)}
end.reduce({}, :merge!).to_json
end
我喜欢以下内容(灵感来自String#html_safe):
get :data, provides: :json do
Record.order(:day).map do |r|
{r.day.to_s => r.data.json_literal}
end.reduce({}, :merge!).to_json
end
我知道我可以使用#as_json将哈希创建移动到模型,但这并不能解决解析和重新编码json时不必要的性能问题。
示例输出:
{
"2010-01-01":{"linux64":12186213,"mac":24131170},
"2010-01-02":{"linux":10650417,"mac":24139611,"win":12210218},
"2010-01-03":{"linux":10628353,"linux64":12184435,"win":12229263}
}
其中作为每个键/值对的值的对象在r.data
中可用作json-string,例如'{"linux":10650417,"mac":24139611,"win":12210218}'
这就是为什么我想避免解析r.data并且只是内联它
我尝试完全绕过JSON解析/转储:
get :data, provides: :json do
"{"+Record.order(:day).map do |r|
"\"#{r.day}\":#{r.data},"
end.reduce(&:+).delete(' ').chop+"}"
end
但性能甚至比不必要的解析版本更差。 (这很奇怪,我不确定字符串连接是慢还是字符串插值......)
答案 0 :(得分:0)
事实证明,实现这一目标的最佳方式实际上是在数据库层,因为postgres可以将json列内联到json对象中,并且比ruby更快地聚合字符串。所以我做到了这一点,并将延迟从30毫秒降低到8毫秒。该方法的主体如下:
Sequel::Model.db.fetch("select json_object_agg(day,data) as jsobj from records;").first[:jsobj]
参考文献: