Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cassandra/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Nosql Cassandra中的MAX()、DISTINCT和group by_Nosql_Cassandra_Cql_Cql3_Nosql Aggregation - Fatal编程技术网

Nosql Cassandra中的MAX()、DISTINCT和group by

Nosql Cassandra中的MAX()、DISTINCT和group by,nosql,cassandra,cql,cql3,nosql-aggregation,Nosql,Cassandra,Cql,Cql3,Nosql Aggregation,我正在尝试重新构建一个SQL数据库Cassandra,这样,我就可以找到SQL查询的Cassandra等价物。我使用CQL3和CassandraV1.2。我用cassandra对db设计进行建模,以便它支持order by子句和非规范化的表来支持join操作。然而,当涉及到DISTINCT、SUM和GROUPBY等值时,我却不知所措 SELECT a1,MAX(b1) FROM demo1 group by a1. SELECT DISTINCT (a2) FROM demo2 where b2

我正在尝试重新构建一个SQL数据库Cassandra,这样,我就可以找到SQL查询的Cassandra等价物。我使用CQL3和CassandraV1.2。我用cassandra对db设计进行建模,以便它支持order by子句和非规范化的表来支持join操作。然而,当涉及到DISTINCT、SUM和GROUPBY等值时,我却不知所措

SELECT a1,MAX(b1) FROM demo1 group by a1.
SELECT DISTINCT (a2) FROM demo2 where b2='sea'
SELECT sum(a3), sum(b3) from demo3 where c3='water' and d3='ocean'
这对我过去几天的工作来说就像是一场闹剧。在Cassandra中是否有一种方法可以对db模式进行建模以支持此类查询?在卡桑德拉我想不出任何办法。如何使用Cassandra实现这些查询


我听说Cassandra上的蜂巢层可能会使这些查询工作。我只是想知道这是否是在Cassandra中支持此类查询的唯一方法。。?请建议其他可能的方法。

卡桑德拉不支持这样的操作。您可以在顶部使用Hive之类的产品,或者Acunu的非免费产品可以满足您的需要


另一个解决办法是自己做这项工作。例如,您可以通过读取特定行中的所有数据并求和来求和。或者维护一个Cassandra计数器以动态递增。

使用Cassandra,您可以通过在插入数据时做更多的工作来解决此类问题-这听起来很慢,但Cassandra专为快速写入而设计,你可能会比你写的数据多读几遍,所以当你考虑整个系统时,它是有意义的。< /P>
我不能确切地告诉您如何创建表来模拟问题,因为这在很大程度上取决于细节。您需要制定一个模式,使您能够在不执行任何动态聚合的情况下获取数据。考虑如何在RDBMS中为查询创建视图,然后尝试考虑如何将数据直接插入到这些视图中,而不是插入到基础表中。这就是你在Cassandra中建模的方式。

虽然这是一个老问题,但它在谷歌搜索结果中出现的频率相当高。所以我想更新一下

Cassandra 2.2+支持用户定义函数和用户定义聚合。警告:这并不意味着你不再需要像@Theo所指出的那样进行数据建模,而是允许你在检索数据时稍微预处理数据

从演示2中选择不同的a2,其中b2='sea'

要实现DISTINCT,您应该定义一个函数和一个agreggate。我将调用函数和聚合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 {};
从演示3中选择suma3、sumb3,其中c3='water'和d3='ocean'

SUM是开箱即用的,正如您所期望的那样工作。见system.sum

按a1从demo1分组中选择a1、MAXb1

分组是个棘手的问题。实际上,没有办法按某个列对结果行进行分组。但您可以做的是创建一个地图,并在地图中手动将它们分组。根据Christopher Batey的博客group by and 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 {};
笔记 正如上面提到的,您仍然需要在数据建模上投入一些时间,不要过度使用这些特性 您必须在cassandra.yaml中设置enable_user_defined_functions=true才能启用这些功能 可以重载函数以支持按不同类型的列进行分组。 参考资料: 和
Cassandra 3.10现在支持分组键和集群键。有关更多详细信息,请参阅。

我确实想到了用于实现求和方法的计数器选项。但是我必须为许多列维护计数器,这些列可以有许多值。但是,这似乎是cassandra支持求和函数的唯一方法。。谢谢你的投入……谢谢你,这对我很有帮助。不管怎样,我还是在这里问问吧。在我的例子中,我有一个计数器列族,我想得到一些带有max计数器的字段,我想知道为什么默认的max函数适用于计数器数据类型,但当我使用您的UDA时它不起作用。它说它需要int,而计数器数据类型没有归类为int。你知道吗?谢谢。您好,根据柜台类型是独一无二的。这意味着您也必须为计数器类型重载函数。例如,自定义max函数将是:创建函数maxCustomcurrent counter,在NULL输入上调用的候选计数器将计数器语言java作为“if current==NULL return candidate”;否则返回Math.maxcurrent,candidate;'创建聚合maxCustomcounter SFUNC maxCustom STYPE计数器INITCOND null;
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;