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

Cassandra query with equals operator on timestamp column not working

我在 Cassandra 中创建了一个 table 如下:

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 从特定日期开始的一行。当我使用 > 运算符时,一切都按预期工作。但是,如果我使用 = 运算符,则不会返回任何数据。

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

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

,则会返回该行

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

我实际上需要这个用于 DELETE 语句,但我不能使用范围运算符,只能使用 =.

我打赌这是不同时区造成的。尝试将您的区域包含在 ...AND load_start_time='2016-01-20 10:10:27.000+0200'

之类的语句中

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

CREATE TABLE Whosebug.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) 输入的时间有毫秒数,但作为文本输入的时间没有。正如您所发现的,当需要完成 in-place 更新或删除时,这可能会出现问题。

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

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

关于"unable to coerce '2016-04-06 13:06:11.534000' to a formatted date (long)"错误,虽然时间戳列在所有版本中实际上存储的是毫秒,但根据版本查询的方式似乎有些差异:

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

我验证了能够 select/insert 在较新的集群中,但不能在旧集群中使用我的 IDE 连接到 9160 Thrift 端口,尚未在 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 uses native binary protocol (9042), previous versions use thrift (9160) although this should not change.