如何在Cassandra中按特定时间范围的字段分组?

时间:2019-07-18 11:19:26

标签: database cassandra

我有一个很大的Cassandra表,包含约15个字段,我想创建许多物化视图来支持我的所有查询。基表上的主键是(CompanyName,ctime),其中ctime是timeuuid。该表记录了在特定时间在特定公司网站上的每次点击。

例如,我的查询之一包括搜索在特定时间范围内(最长一年)使用最多的浏览器。

所以我做到了

CREATE MATERIALIZED VIEW clicks_by_browser 
    AS SELECT CompanyName, ctime, browsername
    FROM companyclicks
    WHERE CompanyName is not null AND ctime is not null AND browsername is not null
    PRIMARY KEY(CompanyName, ctime, browsername)

但这不起作用。当我执行查询时:

SELECT browsername, count(*) from clicks_by_browser
    WHERE CompanyName='example' and id>=minTimeuuid(...) 
    GROUP BY browsername;

Cassandra拒绝了它,因为“ Group by仅支持按主键中声明顺序排列的列组”。所以问题是我在主键中的浏览器名称之前声明了ctime。

所以我尝试将它们的顺序反转为聚簇列,

CREATE MATERIALIZED VIEW clicks_by_browser 
    AS SELECT CompanyName, ctime, browsername
    FROM companyclicks
    WHERE CompanyName is not null AND ctime is not null AND browsername is not null
    PRIMARY KEY(CompanyName, browsername, ctime)

但是现在Cassandra拒绝了相同的查询,因为在WHERE子句中不能限制ctime,因为前一列的browsername不受限制。

那么在Cassandra中目前无法进行这种查询吗?还是我缺少明显的东西?

1 个答案:

答案 0 :(得分:0)

TLDR:这是不可能的。

长回答:
根据Cassandra JIRA, Cassandra当前未在任意列上实现分组依据。按多列分组时,只能按从主键开始声明的顺序按主键列进行分组。

唯一允许的例外是如果您使用相等性限制来限制了前n列。注意,用“ =”限制一列将选择一个组,因此该列中没有要分组的部分,这就是Cassandra允许这样做的原因。然后,您可以按顺序从下一列开始对其余的列进行分组(不能在两列之间跳过)。

因此,要按列分组,所有前面的主键列都必须由“ =”限制,或者必须位于group by子句中。

与上面的查询类似的范围查询失败,因为样本列受到范围的限制,因此仍然具有多个组,但不在group by子句中。在这种情况下,LIKE和IN限制也将不起作用。

我认为您可以尝试的最好的方法是将timeuuid分组为group by,然后在应用程序中进行汇总。

SELECT browsername,id, count(*) from clicks_by_browser
    WHERE CompanyName='example' and id>=minTimeuuid(...) 
    GROUP BY id,browsername;