0

我有一个正在运行的 apache-cassandra-2.2.1 并enable_user_defined_functions设置为truein cassandra.yml。我根据这篇文章定义了一个自定义聚合,如下所示:

CREATE FUNCTION sumFunc(current double, candidate double) CALLED ON NULL INPUT RETURNS double LANGUAGE java AS 'if(current == null) return candidate; return current + candidate;'
CREATE AGGREGATE sum(double) SFUNC sumFunc STYPE double INITCOND null;

当我从 CQLSH 控制台调用它时,我看到了超时:

cqlsh:test> SELECT word, sum(frequency) FROM words;
OperationTimedOut: errors={}, last_host=127.0.0.1

我可以成功运行任何其他查询,我也可以从 scala 运行查询(但我没有得到完整的结果集):

CassandraConnector(conf).withSessionDo { session =>
  val result: ResultSet = session.execute("SELECT word, SUM(frequency) FROM test.words;")
  while(result.isExhausted == false) {
    println(result.one)
  }
}
4

1 回答 1

1

首先,您的查询可能无法达到您的预期,因为它不会按表中的每个单词进行分组。您将获得表中所有频率的总和。要获得一个单词的频率总和,您需要这样做:

SELECT word, sum(frequency) FROM words WHERE word='someword';

其次,我在尝试聚合超过 300,000 行的大型分区时遇到了超时错误(请参阅)。因此,在超时错误出现之前,您的单词表可能太大而无法聚合。我希望 Cassandra 不会对正在进行的查询超时,但它似乎有一些硬编码的超时,无论是否中止任务他们正在进步或实际上被卡住了。

由于您的查询没有 WHERE 子句,因此您正在尝试聚合整个表,而不仅仅是单个分区。这更有可能导致超时错误,因为聚合将发生在分布在多个节点而不是单个节点上的数据上,因此您应该尝试将聚合限制为单个分区。

我认为对于 INITCOND,您希望使用 0 而不是 null。

您的聚合名称可能与内置的系统 sum 函数冲突,因此您可能需要选择不同的名称。但是,看起来您可以使用内置的 sum 函数而不是定义一个函数(Cassandra 2.2 有 sum()、avg()、min() 和 max() 的未记录的内置函数)。

于 2015-09-14T15:16:00.743 回答