【问题标题】:Pre-aggregated datastructure in clojureclojure 中的预聚合数据结构
【发布时间】:2012-03-12 15:43:31
【问题描述】:

在 OLAP 多维数据集中,可以非常快速地查找大量聚合数据。造成这种情况的主要原因是在易于向上组合的操作中预先聚合数据(主要是 +、-、mean、std、max、min 等)。

如何在 clojure 中获得这种“反懒惰”的行为?

我正在考虑类似的事情

(def world-population {:africa 4e8            ;;this is an aggregation!
                       :africa/liberia 3.4e6
                       :africa/ethiopia 7.4e7
                       ...})

如何更新这样的数据结构并确保实体的父级也得到更新?是否必须推出自己的重新实现?

【问题讨论】:

    标签: clojure olap aggregation


    【解决方案1】:

    通过将数据存储在 atom 中,您可以添加 watch - 本质上是 atom 更新时的回调

    类似这样的:

    (def world-population (atom {:africa 4e8
                                 :africa/liberia 3.4e6
                                 ...}))
    
    (add-watch word-population :population-change-key
          (fn [key ref old new]
             (prn "population change")))
    

    您可以在此基础上构建一些事件传播逻辑。

    【讨论】:

    • add-watch 是一种保持结构同步的巧妙方法!谢谢你!
    【解决方案2】:

    您可以将递归汇总函数编写为高阶函数,例如:

    (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)))))
    

    然后可以将其与您喜欢的任何特定汇总操作或层次结构一起使用:

    (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}
    

    如果您有非常大的数据集或多个层次结构等,显然它会变得更加复杂,但这对于许多简单的情况来说应该足够了。

    【讨论】:

    • 这太棒了!使用高阶函数的巧妙方法!地理可能很适合派生,会尝试更多。
    猜你喜欢
    • 1970-01-01
    • 2013-03-15
    • 1970-01-01
    • 2011-05-17
    • 2012-03-05
    • 1970-01-01
    • 2015-01-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多