【发布时间】:2020-01-23 21:43:38
【问题描述】:
tl;博士如何将 IReduceInit 转换为转换值的惰性序列
我有一个数据库查询,它产生了一个相当大的数据集,用于在客户端上进行实时旋转(百万或两行,25 个属性 - 对于现代笔记本电脑来说没问题)。
我的(简化的)堆栈是调用 clojure.jdbc 来获得(我认为是惰性的)结果行序列。我可以通过 ring-json 中间件将其作为主体传递出去,从而将其序列化。 ring-json 在堆上构建响应字符串存在问题,但从 0.5.0 开始可以选择将响应流式传输出去。
通过分析几个失败案例,我发现实际上 clojure.jdbc 是在将整个结果集交还给内存之前实现的。没问题!我决定改用新的 next.jdbc,而不是在那个库中使用 reducible-query。
next.jdbc 中的关键操作是 plan,它返回一个 IReduceInit,我可以使用它来运行查询并获取结果集...
(into [] (map :cc_id) (jdbc/plan ds ["select cc_id from organisation where cc_id = '675192'"]))
["675192"]
但是,这实现了整个结果集,在上述情况下,我会预先提供所有的 id 并在内存中。对一个人来说不是问题,但我通常有很多。
IReduceInit 计划是一个我可以减少的东西,如果我给出一个起始值,所以我可以在减少函数中做输出......(谢谢@amalloy)
(reduce #(println (:cc_id %2)) [] (jdbc/plan ds ["select cc_id from organisation where cc_id = '675192'"]))
675192
nil
...但理想情况下,我想在对它们应用转换函数后将此 IReduceInit 转换为值的惰性序列,因此我可以将它们与 ring-json 和 cheshire 一起使用。我没有看到任何明显的方法。
【问题讨论】:
-
您可能想在 Clojure 邮件列表(Google 群组)或 Clojure Slack 频道上提出这个问题。
标签: clojure ring transducer cheshire