我正在运行apache-cassandra-2.2.1,enable_user_defined_functions
设置为true
cassandra.yml
。我已根据this article定义了一个自定义聚合,如下所示:
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)
}
}
答案 0 :(得分:1)
首先,您的查询可能无法达到您的预期,因为它不会按表格中的每个单词进行分组。您将得到表中所有频率的总和。要获得单词的频率总和,您需要执行此操作:
SELECT word, sum(frequency) FROM words WHERE word='someword';
其次,我在尝试聚合超过300,000行的大型分区时看到了超时错误(请参阅this)。因此,在超时错误开始之前,你的单词表太大而无法聚合。我希望Cassandra不会在正在取得进展的查询上超时,但它似乎有一些硬编码的超时会中止任务,无论是否他们正在进步或实际上被卡住了。
由于您的查询没有WHERE子句,因此您尝试聚合整个表而不是单个分区。这将导致超时错误的可能性更大,因为聚合将发生在多个节点而不是单个节点上的数据上,因此您应该尝试将聚合限制为单个分区。
我认为INITCOND你想要使用0而不是null。
聚合的名称可能与内置系统和函数冲突,因此您可能希望选择其他名称。但是,看起来你可以使用内置的sum函数而不是定义一个(Cassandra 2.2有sum(),avg(),min()和max())的未记录的内置函数。