使用时间戳列上的equals运算符的Cassandra查询不起作用

时间:2016-01-22 13:45:28

标签: cassandra cassandra-2.0 cql cql3 cqlsh

我在Cassandra中创建了一个表:

CREATE TABLE sp.status(
ams text,
load_start_time timestamp,
file_path text,
file_timestamp timestamp,
host text,
load_end_time timestamp,
records_ignored int,
records_imported int,
records_in_file int,
status text,
PRIMARY KEY (ams, load_start_time)
) WITH CLUSTERING ORDER BY (load_start_time DESC)

我想从特定日期中选择一行。当我使用>操作员一切按预期工作。但是如果我使用=运算符,我就不会得到任何数据。

SELECT * FROM sp.status WHERE ams = 'RRG' AND load_start_time='2016-01-20 10:10:27' allow filtering;

在数据库中有一行,其中包含load_start_time的值,如果在上面的查询中我替换= with> for load_start_time。

有人可以解释为什么会这样吗?

我实际上需要这个用于DELETE语句,在那里我不能使用范围运算符,只有=。

3 个答案:

答案 0 :(得分:8)

您是使用dateOf(now())还是使用包含毫秒精度的其他方法来插入行? TIMESTAMP将存储毫秒,但不会显示它。检查此示例:

CREATE TABLE stackoverflow.timestamptest (
    userid text,
    activetime timestamp,
    value text,
    PRIMARY KEY (userid, activetime)
) WITH CLUSTERING ORDER BY (activetime ASC)


INSERT INTO timestamptest (userid,activetime,value) VALUES ('d',dateof(now()),'value1');
INSERT INTO timestamptest (userid,activetime,value) VALUES ('d','2016-01-22 14:57:54+0000','value2');
SELECT userid, value, activetime, blobAsBigint(timestampAsBlob(activetime)) 
  FROM timestamptest WHERE userid='d';


 userid | value  | activetime               | system.blobasbigint(system.timestampasblob(activetime))
--------+--------+--------------------------+---------------------------------------------------------
      d | value2 | 2016-01-22 14:57:54+0000 |                           1453474674000
      d | value1 | 2016-01-22 14:57:54+0000 |                           1453474674912

(2 rows)

通过在blobAsBigint(timestampAsBlob())嵌套函数中包装activetime,我可以看到通过dateOf(now())(912)输入的时间存在毫秒,但不是作为文本输入的时间。正如您所知,当需要完成就地更新或删除时,这可能会出现问题。

尝试使用blobAsBigint(timestampAsBlob())查看是否存在毫秒,然后将这些毫秒添加到DELETE操作的时间戳值。例如:

DELETE FROM timestamptest WHERE userid='d' AND activetime='2016-01-22 14:57:54.912+0000';

答案 1 :(得分:0)

我打赌它是由不同的时区引起的。尝试在...AND load_start_time='2016-01-20 10:10:27.000+0200'

等语句中包含您的区域

答案 2 :(得分:0)

关于“无法强制'2016-04-06 13:06:11.534000'到格式化日期(长)”错误,但是,时间戳列实际上在所有版本中存储了毫秒,似乎存在一些差异如何根据版本进行查询:

Cassandra< = 2.1在查询中似乎不支持毫秒:yyyy-mm-dd'T'HH:mm:ssZ https://docs.datastax.com/en/cql/3.1/cql/cql_reference/timestamp_type_r.html

然而> = 3.0支持它:yyyy-mm-dd'T'HH:mm:ss.ffffffZ https://docs.datastax.com/en/cql/3.3/cql/cql_reference/timestamp_type_r.html

我已验证能够使用我在9160 Thrift端口上连接的IDE在较新的群集中进行选择/插入而不能在旧群集中进行选择/插入,尚未尝试使用cqlsh:

INSERT INTO "sp.status"("ams", "load_start_time")
    VALUES('RRG', '2018-05-01T16:57:18.123+0200')
;

-- same with select, works on new cluster but not old
SELECT * FROM sp.status WHERE ams = 'RRG' AND load_start_time='2018-05-01T16:57:18.123+0200'
;

驱动程序似乎能够映射java日期并在新旧集群中存储毫秒。

  

= Cassandra 2.1 cqlsh使用本机二进制协议(9042),以前的版本使用thrift(9160),尽管这不应该改变。