【问题标题】:Aggregating Set Type in CassandraCassandra 中的聚合集类型
【发布时间】:2019-03-27 20:42:43
【问题描述】:

我正在尝试聚合每行都包含 Set 列的行。我希望结果包含所有集合的总和,其中 null 相当于空集。我希望这样的查询:“通过 my_key_column 从 my_table 组中选择 sum(my_set_column)”来执行此操作,但此聚合不支持集合类型。有谁知道使用现有的 cassandra 内置插件来聚合它的方法?谢谢!

【问题讨论】:

    标签: cassandra


    【解决方案1】:

    您必须编写一个 udf(对单个集合求和)或 uda(对多个集合求和),但它应该非常简单。类似的东西

    CREATE FUNCTION set_sum(values set<int>)
    CALLED ON NULL INPUT
    RETURNS int
    LANGUAGE java
    AS $$
      if (values == null)
        return 0;
    
      int total = 0;
      for (int v : values)
        total += v;
      return total;
    $$;
    

    然后SELECT set_sum(value_column) FROM my_table WHERE id = 'key'; 将聚合每一行中设置列的值。如果你想合并多行(即与 group by),你需要使用 UDA,它可以使用上面的函数和 int 状态来替换 total 而不是每次都从 0 开始。

    【讨论】:

    • 我担心会是这样。无论如何,谢谢你的回答,我现在就试试看!
    • 其实我要找的是元素的集合加法,例如{1, 3, 5} + {2, 4} = {1, 2, 3, 4, 5, 6}。我尝试使用 UDF,但这不会保留状态,所以我无法累积。我尝试使用 UDA,但这需要对我的所有查询进行大量重写(这是不可行的)以请求 UDA 作为列而不是现有列。你写过这样的东西吗?
    【解决方案2】:

    我能够使用以下 UDF/UDA 完成这项工作。如果将来有其他人需要,这可以被视为通用集合聚合器:

    CREATE OR REPLACE FUNCTION agg_set_func(state tuple<int, set<bigint>>, val set<bigint>) CALLED ON NULL INPUT RETURNS tuple<int, set<bigint>> LANGUAGE java AS 
    $$
        if (val == null) {
            return state;
        }
        Set<Long> s = state.getSet(1, Long.class);
        s.addAll(val);
        state.setSet(1, s);
        return state;
    $$;
    
    CREATE OR REPLACE FUNCTION agg_set_func_final(state tuple<int, set<bigint>>) CALLED ON NULL INPUT RETURNS set<bigint> LANGUAGE java AS 
    $$
        return state.getSet(1, Long.class);
    $$;
    
    CREATE AGGREGATE agg_set(set<bigint>) 
    SFUNC agg_set_func
    STYPE tuple<int, set<bigint>>
    FINALFUNC agg_set_func_final
    INITCOND (0,{});
    

    【讨论】:

      猜你喜欢
      • 2015-04-19
      • 2016-08-10
      • 2018-07-17
      • 1970-01-01
      • 2015-01-06
      • 2021-11-27
      • 2012-12-17
      • 2012-11-16
      • 2014-08-26
      相关资源
      最近更新 更多