2013-11-03 9 views
16

I Tabelle unten haben in CQL-Ungültige Anforderung: Keine indizierten Spalten in by-columns-Klausel mit Equal-Operator: CQL-Fehler?

create table test (
    employee_id text, 
    employee_name text, 
    value text, 
    last_modified_date timeuuid, 
    primary key (employee_id) 
    ); 

I paar Datensätze in der obigen Tabelle wie folgt eingefügt, die ich ich tat Use-Case-Szenario-

insert into test (employee_id, employee_name, value, last_modified_date) values ('1', 'e27', 'some_value', now()); 
insert into test (employee_id, employee_name, value, last_modified_date) values ('2', 'e27', 'some_new_value', now()); 
insert into test (employee_id, employee_name, value, last_modified_date) values ('3', 'e27', 'some_again_value', now()); 
insert into test (employee_id, employee_name, value, last_modified_date) values ('4', 'e28', 'some_values', now()); 
insert into test (employee_id, employee_name, value, last_modified_date) values ('5', 'e28', 'some_new_values', now()); 

Jetzt in unserem tatsächlichen Einsetzen wird Abfrage auswählen für - geben Sie mir die gesamte Mitarbeiter-ID für Mitarbeitername e27.

select employee_id from test where employee_name = 'e27'; 

Und das ist der Fehler Ich erhalte -

Bad Request: No indexed columns present in by-columns clause with Equal operator 
Perhaps you meant to use CQL 2? Try using the -2 option when starting cqlsh. 

Gibt es etwas falsch mache ich hier?

Meine Anwendungsfälle sind im Allgemeinen -

  1. Gib mir alles für eine der employee_name?
  2. Gib mir alles, was sich in den letzten 5 Minuten verändert hat?
  3. Geben Sie mir die neueste employee_id und den Wert für einen der Mitarbeiter_Name?
  4. Geben Sie mir die ganze employee_id für irgendeinen der employee_name?

mir läuft Cassandra 1.2.11

Antwort

24

Die allgemeine Regel ist einfach: „Sie können nur Abfrage von Spalten, die Teil des Schlüssels sind“. Zur Erklärung würden alle anderen Abfragen einen vollständigen Scan der Tabellen erfordern, was eine Menge an Datensieben bedeuten könnte.

Es gibt Dinge, die diese Regel ändern können:

  1. Verwendung Sekundärindizes für Spalten mit geringer Mächtigkeit (mehr Details here)
  2. definieren mehrspaltigen Schlüssel (zB PRIMARY KEY (col1, col2), welche Abfragen wie col1 = value1 erlauben würde, und col1 = value1 and col2 COND)
  3. verwenden ALLOW FILTERING in Abfragen. Dies wird zu einer Warnung führen, da Cassandra viele Daten durchforsten muss und es keine Leistungsgarantien geben wird. Weitere Details details of ALLOW FILTERING in CQL und this SO thread sehen nehmen
+1

Als Referenz können Sie einen Sekundärschlüssel mit 'CREATE INDEX ON Tests (Mitarbeitername);' – chinglun

+0

Der Link in '1' trifft eine 500 Konsistenz – Squidly

+0

Dann wirft es einen weiteren Fehler über Non-PRIMARY-Schlüssel. Hinweis: In meinem Beispiel ist die Spalte Nachname. { 'ResponseError', Nachricht: 'Nachname gefunden Non PRIMARY KEY in where clause', info: Name [ResponseError Nicht Nachname PRIMARY KEY in where-Klausel gefunden] 'eine Fehlermeldung vom Server', Code: 8704, Abfrage: 'UPDATE Benutzer SET Alter = 36 WHERE Nachname = \' Jones \ '} –

16

Cassandra ein wenig Einige von uns wurden von einigen der zusätzlichen Sachen verdorben RDBMS hat für Sie :) Gewöhnung, dass Sie nicht von NoSQL kostenlos bekommt.

Wenn Sie an eine reguläre RDBMS-Tabelle denken, wenn Sie SELECT für eine Spalte ohne Index auswählen, muss die Datenbank einen vollständigen Tabellenscan durchführen, um alle gewünschten Übereinstimmungen zu finden. Dies ist ein Nein-Nein in Cassandra, und es wird sich beschweren, wenn Sie versuchen, dies zu tun. Stellen Sie sich vor, Sie hätten 10^32 Treffer zu dieser Suchanfrage gefunden? Es ist keine vernünftige Frage.

In Ihrer Tabelle haben Sie * PRIMARY KEY (employee_id); * Dies ist der primäre und eindeutige Identifizierungsschlüssel der Zeile. Sie können jetzt SELECT * von TEST wo employee_id = '123'; das ist völlig in Ordnung und Cassandra wird das Ergebnis gerne zurückgeben.

Ihre SELECT von TEST WHERE employee_name = 'e27'; sagt Cassandra, dass sie JEDE Platte lesen soll, bis sie eine Übereinstimmung auf "e27" findet. Ohne einen Index, auf den Sie sich verlassen können, bittet es Sie höflich, es zu vergessen.

Wenn Sie nach einer Spalte filtern möchten, stellen Sie sicher, dass Sie einen Index für diese Spalte haben, damit Cassandra die von Ihnen benötigte Filterung durchführen kann.