【发布时间】:2019-03-27 20:42:43
【问题描述】:
我正在尝试聚合每行都包含 Set 列的行。我希望结果包含所有集合的总和,其中 null 相当于空集。我希望这样的查询:“通过 my_key_column 从 my_table 组中选择 sum(my_set_column)”来执行此操作,但此聚合不支持集合类型。有谁知道使用现有的 cassandra 内置插件来聚合它的方法?谢谢!
【问题讨论】:
标签: cassandra
我正在尝试聚合每行都包含 Set 列的行。我希望结果包含所有集合的总和,其中 null 相当于空集。我希望这样的查询:“通过 my_key_column 从 my_table 组中选择 sum(my_set_column)”来执行此操作,但此聚合不支持集合类型。有谁知道使用现有的 cassandra 内置插件来聚合它的方法?谢谢!
【问题讨论】:
标签: cassandra
您必须编写一个 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 开始。
【讨论】:
我能够使用以下 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,{});
【讨论】: