2015-12-28 6 views
5

Ich habe eine Tabelle Schicht mit folgendem Code erstellt:order by-Klausel funktioniert nicht in Cassandra Abfrage

CREATE TABLE layer (
    layer_name text, 
    layer_position text, 
    PRIMARY KEY (layer_name, layer_position) 
) WITH CLUSTERING ORDER BY (layer_position DESC) 

ich die folgende Abfrage verwenden, um Daten aus der Schicht Tabelle zu holen in absteigender Reihenfolge (Schicht):

$select = new Cassandra\SimpleStatement(<<<EOD 
         select * from layer ORDER BY layer_position DESC 
EOD 
        ); 

$result = $session->execute($select); 

Aber diese Abfrage funktioniert nicht. Kann mir bitte jemand helfen?

+0

Vielleicht hilft Ihnen das: - http://www.planetcassandra.org/blog/cql-cassandra-query-language/ – Hemdip

+0

danke, aber ich habe das auch versucht, aber es kann nicht funktionieren. –

+0

Wenn ich versuche, Reihenfolge zu verwenden, dann gibt es einen Fehler wie: ORDER BY wird nur unterstützt, wenn der Partitionsschlüssel durch einen EQ oder einen IN eingeschränkt ist. aber ich bekomme dieses Problem nicht. –

Antwort

4

Einfach ausgedrückt, erzwingt Cassandra nur die Sortierreihenfolge innerhalb einen Partitionsschlüssel.

PRIMARY KEY (layer_name, layer_position) 
) WITH CLUSTERING ORDER BY (layer_position DESC) 

In diesem Fall layer_name ist die Partition Schlüssel. Wenn Sie in Ihrer WHERE-Klausel layer_name angeben, werden Ihre Ergebnisse für diesen Wert layer_name von layer_position bestellt.

SELECT * FROM layer WHERE layer_name = 'layer1'; 

Sie müssen ORDER BY nicht angeben. Alles, was ORDER BY wirklich tun kann, ist eine Sortierrichtung (aufsteigend oder absteigend).

Cassandra funktioniert auf diese Weise, weil es Daten in der Reihenfolge sortiert, in der es auf der Festplatte sortiert ist. Ihre Partitionsschlüssel sind nach Hash-Token-Werten sortiert, weshalb die Ergebnisse einer ungebundenen WHERE-Klausel zufällig geordnet erscheinen.

EDIT

Ich habe Daten state_id Spalte holen verwenden und es sollte durch layer_position sein Auftrag.

Cassandra-Tabellen sind für eine bestimmte Abfrage optimiert. Während dies zu einer hohen Leistungsfähigkeit führt, besteht der Nachteil darin, dass die Abfrageflexibilität begrenzt ist. Der Weg, dies zu lösen, besteht darin, Ihre Daten in eine zusätzliche Tabelle zu duplizieren, die speziell für diese Abfrage entwickelt wurde.

CREATE TABLE layer_by_state_id (
    layer_name text, 
    layer_position text, 
    state_id text, 
    PRIMARY KEY (state_id, layer_position, layer_name) 
) WITH CLUSTERING ORDER BY (layer_position DESC, layer_name ASC); 

Diese Tabelle wird wie folgt ermöglichen, Abfragen zu arbeiten:

wird
SELECT * FROM layer WHERE state_id='thx1138'; 

Und die Ergebnisse von layer_position, state_id innerhalb der gewünschten sortiert werden.

Jetzt mache ich ein paar Annahmen, die Sie untersuchen wollen:

  • ich davon aus, dass mir state_id ein guter Partitionierungsschlüssel ist. Das bedeutet, dass die Kardinalität hoch genug ist, um eine gute Verteilung im Cluster zu ermöglichen, aber die Kardinalität niedrig genug ist, dass genügend CQL-Zeilen zurückgegeben werden, damit sich die Sortierung lohnt.
  • Ich gehe davon aus, dass die Kombination state_id und layer_positionnicht genug ist, um jede Zeile eindeutig zu identifizieren. Daher stelle ich die Eindeutigkeit sicher, indem ich layer_name als zusätzlichen Clustering-Schlüssel hinzufüge. Du kannst es vielleicht oder auch nicht brauchen, aber ich vermute, dass du es tust.
  • Ich gehe davon aus, dass die Verwendung von state_id als Partitionierungsschlüssel kein ungebundenes Wachstum zeigen wird, um Cassandras Grenze von 2 Milliarden Zellen pro Partition zu erreichen. Wenn dies der Fall ist, müssen Sie möglicherweise eine zusätzliche Partition "Bucket" hinzufügen.
+0

Hallo, ich habe noch ein zusätzliches Feld state_id in dieser Layer-Tabelle. Ich muss Daten mit State_id Spalte abrufen und es sollte Reihenfolge von Layer_position sein. state_id Spalte enthält einen wiederholten Wert. In diesem Fall habe ich Ihren Code versucht, aber ich bekomme kein erwartetes Ergebnis. –

+0

@NiraliKavar Bearbeitung vorgenommen. – Aaron

+0

@ Aaron - Vielen Dank ... jetzt funktioniert es nach meinen Erwartungen. –

0

Sie können order by nicht direkt in Cassandra verwenden.

Sie können order by nur auf Clusterspalten anwenden, wenn Ihr Partitionsschlüssel durch EQ oder IN eingeschränkt wird.

+3

Es tut mir leid, aber was meinst du mit der unteren Zeile. "Sie können die Reihenfolge nur dann in Cluster-Spalten anwenden, wenn Ihr Partitionsschlüssel durch EQ oder IN eingeschränkt wird." Ich bin ein Kassandra-Noob. – NishM

+0

@shubhamsharma Danke. Ich habe es herausgefunden, nachdem ich durch zahlreiche Beiträge gegraben habe. Sollte wieder zu SO kommen und meine Ergebnisse gepostet haben. :( – NishM