时间戳列上的Cassandra查询不返回Java的即时类型的值

时间:2017-01-24 00:24:57

标签: java cassandra datastax

我试图弄清楚如何使用java 8 api在特定日期的某个时间间隔内查询cassandra。

例如,假设我有一个组表。

create table groups(
group_name text,
updated_on timestamp
primary key (group_name, updated_on)
);

我在表格中有以下记录

group_name    updated_on
RealGroup     2017-01-01 04:30:00-0800
RealGroup     2017-01-01 04:30:15-0800
MockGroup     2017-02-05 04:30:00-0800

我想像以下一样对cassandra执行查询。

select * from groups where group_name = 'RealGroup' and updated_on >= 2017 01-01 04:30:00-0800 AND <= 2017-01-01- 04:30:59-0800'

基本上,我希望在MINUTE区间内获取数据。

我正在使用带有datastax api的GroupAccessor。

@Query("SELECT * FROM GROUPS WHERE GROUP_NAME = :groupName AND UPDATED_ON>= :startDate AND UPDATED_ON<= :endDate")
Result<Group> getResults(@Param("groupName") String groupName, @Param("startDate") Instant startDate, @Param("endDate") Instant endDate);

我的问题是,客户电话会是什么样子?什么是使用java 8 api发送请求的正确方法?

我使用以下内容,但它给了我奇怪的结果。

LocalDateTime startDate = LocalDateTime.of(2017, Month.JANUARY, 1, 4, 30);
LocalDateTime endDate = LocalDateTime.of(2017, Month.JANUARY, 1, 4, 31);
Instant start = startDate.toInstant(ZoneOffset.UTC);
Instant end = endDate.toInstant(ZoneOffset.UTC);

Result<Group> dateGroup = groupAccessor.getResults("RealGroup", start, end);

所以实际上,上面的代码应该返回2行。

RealGroup     2017-01-01 04:30:00-0800
RealGroup     2017-01-01 04:30:15-0800

但不返回。

1 个答案:

答案 0 :(得分:3)

您正在对timestamp类型的列进行群集。 timestamp类型代表

  

自标准基准时间以来称为数毫秒   时代:1970年1月1日格林尼治标准时间00:00:00

使用CQLSH时,可以使用表示该毫秒数的整数值

INSERT INTO groups (group_name , updated_on ) VALUES ( 'MockGroup', 1485221928341);

或者您可以使用

  

以下任何ISO 8601格式的字符串文字:

yyyy-mm-dd HH:mm  
yyyy-mm-dd HH:mm:ss  
yyyy-mm-dd HH:mmZ  
yyyy-mm-dd HH:mm:ssZ  
yyyy-mm-dd'T'HH:mm  
yyyy-mm-dd'T'HH:mmZ  
yyyy-mm-dd'T'HH:mm:ss  
yyyy-mm-dd'T'HH:mm:ssZ  
yyyy-mm-dd'T'HH:mm:ss.ffffffZ  
yyyy-mm-dd  
yyyy-mm-ddZ  
     

其中Z是RFC-822 4位数时区,表示时区与UTC的区别

在您的示例中,您已指定

2017 01-01 04:30:00-0800

其中包含比UTC晚8小时的时区。但是当您使用Java代码发出请求时,您创建了一个Instant,它意味着代表UTC时区的当地时间4:30(即0偏移)。那是什么

Instant start = startDate.toInstant(ZoneOffset.UTC);

一样。因此,您在数据库中的实际情况是8小时。相反,请在当地时间4:30比UTC时间晚8小时的时区创建Instant

Instant start = startDate.toInstant(ZoneOffset.ofHours(-8));
Instant end = endDate.toInstant(ZoneOffset.ofHours(-8));

这可以让你回到你想要的两个小组。

  

我有没有办法处理区域?

是的,使用整数(就像我的第一个例子)。理解普通数字比格式化字符串更难理由。

或者,您可以在日期字符串末尾使用Z来表示没有偏移UTC的Zulu时区。例如,

INSERT INTO groups (group_name , updated_on ) VALUES ( 'MockGroup', '2017-02-05 04:31:00Z');

显然,从Java代码来看,Instant没有时区概念,它只是代表一个时间戳,就像Cassandra中的类型一样,所以你可以直接使用它。