只有日期范围扫描Cassandra CQL时间戳

时间:2015-01-14 11:43:20

标签: java cassandra cassandra-cli nosql

我有一张如下表所示的表格。

CREATE TEST(
 HOURLYTIME TIMESTAMP,
 FULLTIME TIMESTAMP,
 DATA TEXT,
 PRIMARY KEY(HOURLYTIME,FULLTIME)
)

我插入了记录(2014-12-12 00:00:00,2014-12-12 00:00:01,'Hello World')

我想根据HOURLYTIME字段中的日期时间范围进行搜索,该字段包含每小时记录。当我尝试使用token()时

select * from TEST where token(HOURLYTIME)=token('2014-12-12')

获取该日期的所有记录,仅返回一小时记录,即

 2014-12-12 **00:00:00**

如果我添加日期范围

select * from TEST where token(HOURLYTIME)>=token('2014-12-12') AND token(HOURLYTIME)<=token('2014-12-14');

它给出了错误:为起始绑定找到了多个限制

如何解决此问题。

我能够使用FULLTIME进行扫描,但我需要提供ALLOW FILTERING,它将扫描整个记录和低效的。

3 个答案:

答案 0 :(得分:4)

要进行范围查询,您需要将此列作为群集列。

在这种情况下它将是高效的,因为聚类列被存储排序。如果要搜索数据,则需要指定分区键。

举个例子,我将device_id用作分区键:

CREATE TABLE IF NOT EXISTS mykeyspace.device_data (
 DEVICE_ID text,
 HOURLYTIME TIMESTAMP,
 FULLTIME TIMESTAMP,
 DATA TEXT,
 PRIMARY KEY (DEVICE_ID, HOURLYTIME, FULLTIME)
);

INSERT INTO mykeyspace.device_data (device_id, hourlytime, fulltime, data)
values('Spam machine', '2014-12-12 00:01:00','2014-12-12 00:00:01','Hello World1');

INSERT INTO mykeyspace.device_data (device_id, hourlytime, fulltime, data)
values('Spam machine', '2014-12-12 00:02:00','2014-12-12 00:00:02','Hello World2');

INSERT INTO mykeyspace.device_data (device_id, hourlytime, fulltime, data)
values('Spam machine', '2014-12-12 00:03:00','2014-12-12 00:00:03','Hello World3');

-- Effective range query
SELECT * FROM mykeyspace.device_data
WHERE device_id = 'Spam machine'
    AND hourlytime > '2014-12-12 00:00:00'
    AND hourlytime < '2014-12-12 00:02:00';

或者另一个例子,我按天分区数据(这将很好地导致跨群集传播数据),并执行范围查询:

CREATE TABLE IF NOT EXISTS mykeyspace.day_data (
     DAYTIME timestamp,
     HOURLYTIME TIMESTAMP,
     FULLTIME TIMESTAMP,
     DATA TEXT,
     PRIMARY KEY (DAYTIME, HOURLYTIME, FULLTIME)
);

INSERT INTO mykeyspace.day_data (DAYTIME, hourlytime, fulltime, data)
values('2014-12-12', '2014-12-12 00:01:00','2014-12-12 00:00:01','Hello World1');

INSERT INTO mykeyspace.day_data (DAYTIME, hourlytime, fulltime, data)
values('2014-12-12', '2014-12-12 00:02:00','2014-12-12 00:00:02','Hello World2');

INSERT INTO mykeyspace.day_data (DAYTIME, hourlytime, fulltime, data)
values('2014-12-12', '2014-12-12 00:03:00','2014-12-12 00:00:03','Hello World3');

SELECT * FROM mykeyspace.day_data
WHERE daytime = '2014-12-12'
    AND hourlytime > '2014-12-12 00:00:00'
    AND hourlytime < '2014-12-12 00:02:00';

关于PlanetCassandra

的时间序列数据,有非常有用的文章

答案 1 :(得分:3)

如果没有明确要求允许过滤,则不允许您将主键限制在某个范围内。这可以防止需要全表扫描的查询,因为您注意到这些查询速度很慢,并且无法针对真正的大数据大小进行扩展。其原因是主键值是随机散列的,因此指定一键主键值基本上与提供两个松散耦合的随机数相同。例如,在您的情况下,日期很可能不是单调散列的。这意味着您希望日期哈希值小于另一个值的哈希将返回完全随机的数据集。

这里的问题是您的表设置不允许您实际想要执行的查询。您需要对表进行建模,以便可以从单个分区获取所需的信息。

答案 2 :(得分:0)

日期范围查询工作正常。我使用以下版本

[cqlsh 4.1.0 | Cassandra 2.0.4 | CQL spec 3.1.1 | Thrift protocol 19.39.0]

旧版本可能存在问题。请检查。