2017-01-24 1 views
1

Ich versuche herauszufinden, wie ich Cassandra in einem winzigen Intervall an bestimmten Daten mit Java 8 API abfragen kann.Cassandra Abfrage auf Zeitmarke Spalte gibt keine Werte mit Java Instant-Typ

Stellen Sie sich zum Beispiel vor, ich habe eine Gruppentabelle.

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

Ich habe folgende Datensätze in der Tabelle

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 

Ich mag würde eine Abfrage cassandra wie die folgende auszuführen.

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' 

Also im Wesentlichen möchte ich Daten über die Minute Intervall erhalten.

Ich benutze ein GroupAccessor mit dem datastax api.

@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); 

Meine Frage ist, wie würde der Client Anruf aussehen? Was ist der richtige Weg, um die Anfrage mit Java 8 API zu senden?

Ich benutze das folgende, aber es gibt mir seltsame Ergebnisse.

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); 

In der Realität sollte dieser Code oben 2 Zeilen zurückgeben.

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

aber gibt keine zurück.

+0

_Odd_ wie? Was ist unerwartet? –

+0

Die Rückgabe ist leer. – user1172490

+0

Anstelle von 'ZoneOffset.UTC' möchten Sie ein' ZoneOffset', das die '-0800' repräsentiert, die Sie in Ihrer CQL-Abfrage haben. –

Antwort

2

Sie gruppieren sich um eine Spalte des Typs timestamp. Der timestamp Typ stellt

eine Anzahl von Millisekunden seit Beginn der Standard-Zeitbasis als die Epoche bekannt: 1. Januar 1970 um 00:00:00 GMT

Wenn CQLSH verwenden, können Sie eine ganze Zahl verwenden dass die Anzahl von Millisekunden Wert

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

oder Sie können

verwenden

ein Zeichenfolgenliteral in einen der folgenden ISO 8601-Formate:

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 

wo Z die RFC-822 4-stellige Zeitzone ist,

In Ihrem Beispiel der Zeitzone des Unterschied von UTC exprimierenden , Sie haben

2017 01-01 04:30:00-0800 

angegeben, die eine Zeitzone enthält, die 8 Stunden hinter UTC liegt. Aber wenn Sie Ihre Anfrage in Java-Code gestellt haben, haben Sie eine Instant erstellt, die 4:30 Ortszeit von der UTC-Zeitzone (dh 0-Offset) darstellen soll. Das ist was

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

tut. Sie sind also 8 Stunden frei, was tatsächlich in der Datenbank ist.Erstellen Sie stattdessen eine Instant aus einer Zeitzone, die 8 Stunden hinter UTC um 4:30 Ortszeit ist.

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

Dies sollte Ihnen die zwei Gruppen zurückgeben, die Sie wollten.

Gibt es einen Weg, wo ich nicht mit Zonen umgehen muss?

Ja, verwenden Sie ganze Zahlen (wie mein erstes Beispiel). Es ist nur schwieriger, über einfache Zahlen nachzudenken als formatierte Strings.

Oder Sie können Z am Ende Ihrer Datumszeichenkette verwenden, um die Zulu-Zeitzone anzugeben, die keine Offset-UTC hat. Zum Beispiel

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

Offensichtlich von Java-Code, hat das Instant kein Konzept der Zeitzone, stellt sie einfach einen Zeitstempel, ebenso wie die Art in Cassandra, so können Sie es direkt verwenden.

+0

Wenn ich einen sofortigen Datensatz mit dem Treiber von datastax speichere, scheint der Wert des Zeitstempels in Cassandra immer in einem menschlichen lesbaren Format zu enden, d. H. 2017-01-23 06: 40: 43-0800 anstelle einer Ganzzahl in Millisekunden. Wie änderst du es? – user1172490

+0

@ user1172490 So zeigt CQLSH es an. [Hier] (http://stackoverflow.com/questions/28547616/cassandra-cqlsh-how-to-show-microseconds-milliseconds-for-timestamp-columns) sind ein paar Tricks, um es als Integer zu drucken. –

Verwandte Themen