cla*_*laj 6 olap clojure aggregation
在OLAP-cubes中,可以对大量聚合数据进行快速查找.这样做的主要原因是一个预先聚合操作中的数据,这些数据易于向上组合(主要是+, - ,mean,std,max,min等等).
如何在clojure中获得这种"反懒惰"行为?
我正在考虑类似的事情
(def world-population {:africa 4e8 ;;this is an aggregation!
:africa/liberia 3.4e6
:africa/ethiopia 7.4e7
...})
Run Code Online (Sandbox Code Playgroud)
如何更新这样的数据结构并确保实体的父级也更新?有人必须推出自己的ref实现吗?
您可以将递归汇总函数编写为高阶函数,例如:
(defn rollup
([data heirarchy func]
(loop [top (second (first heirarchy))]
(if (nil? (heirarchy top))
(rollup data heirarchy func top)
(recur (heirarchy top)))))
([data heirarchy func root]
(let [children (reduce (fn [l [k v]] (if (= v root) (cons k l) l)) '() heirarchy)
data (reduce (fn [d c] (if (d c) d (rollup d heirarchy func c))) data children)
child-values (map data children)]
(assoc data root (apply func child-values)))))
Run Code Online (Sandbox Code Playgroud)
然后可以将其与您喜欢的任何特定汇总操作或层次结构一起使用:
(def populations { :africa/liberia 3.4e6
:africa/ethiopia 7.4e7})
(def geography {:africa/liberia :africa
:africa/ethiopia :africa
:africa :world})
(rollup populations geography +)
=> {:africa 7.74E7,
:world 7.74E7,
:africa/ethiopia 7.4E7,
:africa/liberia 3400000.0}
Run Code Online (Sandbox Code Playgroud)
显然,如果您有非常大的数据集或多个层次结构等,它会变得更加复杂,但这对于许多简单的情况来说应该足够了。