执行cassandra表的范围查询

时间:2014-07-23 19:54:13

标签: cassandra cassandra-2.0 datastax

我正在尝试使用以下架构存储数据:

 CREATE TABLE temp_humidity_data (
                asset_id text, 
                date text, 
                event_time timestamp, 
                temprature int, 
                humidity int,
                PRIMARY KEY((asset_id, date),event_time)
            )

我已关注数据文章“时间序列建模入门” - http://planetcassandra.org/blog/post/getting-started-with-time-series-data-modeling/

然而,对于这个数据模型,一件不起作用的是在两个日期之间返回数据的查询。我该怎么做?

如果我这样做:

select * from temp_humidity_data 
where asset_id='1234' AND date >= '2010-04-02' AND date <= '2011-04-03';

它给了我以下错误:

  

code = 2200 [无效查询] message =“只有EQ和IN关系   分区键支持(除非你使用token()函数)“

理解有一种方法可以做IN运算符,但我不想把所有这些日期都放在'IN'运算符中。有没有办法在两个日期之间使用上面的表定义数据时进行查询?

2 个答案:

答案 0 :(得分:6)

主键中的第一个键(在您的情况下为复合键)负责将数据分散到不同的分区。每个分区完全保存在单个节点(及其副本)上。即使您请求的查询是可能的(如果您只将日期作为主要日期并使用了byteorderedpartitioner - 默认为murmur3),它将有效地在您的群集中执行完整扫描。可以想象这与没有索引的列上的rdbms中的全表扫描类似,只是现在全表扫描跨越多台机器。

此处使用复合分区键的目标是确保没有分区变得无法管理。它还会消除您跨日期进行范围查询的能力。如果您认为资产的数据可以放在单个分区中,则可以将日期作为第一个集群密钥。这将启用查询。但是,资产的所有行都将位于单个分区上。这可能是一个问题(作为最大分区大小,目标通常是100MB左右 - 尽管有例外),并且群集中可能会出现热点(占用非常繁忙的分区的节点将很忙,而其他节点少了)。另一种方法是维护手动存储桶 - 添加bucketid int作为分区键的一部分[即(asset_id,bucket_id)],将日期作为第一个集群密钥,并保持应用程序代码的分组。这将在您控制的多个分区中分配资产的数据。这需要一些计算,并且需要您自己查询每个桶 - 但是会阻止热点,并允许您的日期范围查询。如果特定资产的数据超出单个分区大小,但是可以通过存储桶进行管理,那么显然只会这样做。

如果您绝对必须根据日期进行分区,请考虑像Spark和Shark这样的事情进行高效的帖子聚合。

希望有所帮助。

答案 1 :(得分:2)

没有。只有两次之间。 (asset_id,date)使不同的日期在不同的分区中生效。由于这些值的组合被一起散列,因此C *无法知道特定范围内的所有日期在何处而不搜索每一行。

如果要根据日期进行范围扫描,则日期必须是群集密钥的一部分,而不是分区密钥。