虽然这是一个老问题,但它在 Google 搜索结果中的出现率很高。所以我想提供一个更新。
Cassandra 2.2+ 支持用户定义的函数和用户定义的聚合。 警告:这并不意味着您不必再进行数据建模(正如@Theo 所指出的那样),它只是允许您在检索时稍微预处理数据。
SELECT DISTINCT (a2) FROM demo2 where b2='sea'
要实现DISTINCT,您应该定义一个函数和一个聚合门。我将调用函数和聚合 uniq 而不是 distinct 来强调它是用户定义的事实。
CREATE OR REPLACE FUNCTION uniq(state set<text>, val text)
CALLED ON NULL INPUT RETURNS set<text> LANGUAGE java
AS 'state.add(val); return state;';
CREATE OR REPLACE AGGREGATE uniq(text)
SFUNC uniq STYPE set<text> INITCOND {};
那你按如下方式使用:
SELECT uniq(a2) FROM demo2 where b2='sea';
SELECT sum(a3), sum(b3) from demo3 where c3='water' and d3='ocean'
SUM 是开箱即用的,可以按照您的预期工作。见system.sum。
SELECT a1,MAX(b1) FROM demo1 group by a1
GROUP BY 是一个棘手的问题。实际上,没有办法按某列对结果行进行分组。但是您可以做的是创建一个map<text, int> 并在地图中手动将它们分组。基于 Christopher Batey 博客中的一个示例,group-by 和 max:
CREATE OR REPLACE FUNCTION state_group_and_max(state map<text, int>, type text, amount int)
CALLED ON NULL INPUT
RETURNS map<text, int>
LANGUAGE java AS '
Integer val = (Integer) state.get(type);
if (val == null) val = amount; else val = Math.max(val, amount);
state.put(type, val);
return state;
' ;
CREATE OR REPLACE AGGREGATE state_group_and_max(text, int)
SFUNC state_group_and_max
STYPE map<text, int>
INITCOND {};
那你按如下方式使用:
SELECT state_group_and_max(a1, b1) FROM demo1;
注意事项
- 如上所述,您仍然需要在数据建模上投入一些时间,不要过度使用这些功能
- 您必须在
cassandra.yaml 中设置enable_user_defined_functions=true 才能启用这些功能
- 您可以重载函数以支持按不同类型的列进行分组。
参考资料: