虽然这是一个老问题,但它在谷歌搜索结果中的出现率很高。所以我想提供一个更新。
Cassandra 2.2+ 支持用户定义的函数和用户定义的聚合。警告:这并不意味着您不必再进行数据建模(正如@Theo 所指出的那样),它只是允许您在检索时稍微预处理数据。
从 demo2 中选择 DISTINCT (a2),其中 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;
笔记
- 如上所述,您仍然需要在数据建模上投入一些时间,不要过度使用这些功能
- 您必须
enable_user_defined_functions=true
在您的设置中cassandra.yaml
启用这些功能
- 您可以重载函数以支持按不同类型的列进行分组。
参考: