EDIT1: Ein Fall wurde hinzugefügt, um das Problem nach der ursprünglichen Frage zu beschreiben.
Ich möchte eine Spalte abfragen, die nicht Teil meines Schlüssels ist. Wenn ich das richtig verstanden habe, muss ich einen sekundären Index für diese Spalte definieren. Ich möchte jedoch eine Größer-Bedingung (nicht nur eine Gleichheitsbedingung) verwenden, die immer noch nicht unterstützt wird.
Vermisse ich etwas? Wie würden Sie dieses Problem angehen?
Mein gewünschtes Setup:
%Vor%Da in Cassandra 1.1.6 ein sekundärer Index für ColumnFamilies mit zusammengesetzten Schlüsseln noch nicht unterstützt wird, muss ich mich auf eine vorübergehende Lösung mit dem Löschen eines Schlüssels festlegen, aber ich habe immer noch das gleiche Problem mit nicht gleichwertigen Bedingungen.
Gibt es eine andere Möglichkeit, dies zu beheben?
Danke für Ihre Zeit.
Relevante Quellen: Ссылка Ссылка
EDIT1
Hier ist ein Fall, der das Problem erklären wird. Wie rs-atl bemerkte, könnte es sich um ein Datenmodellproblem handeln. Nehmen wir an, ich halte eine Spaltenfamilie aller Benutzer auf Stackoverflow. Für jeden Benutzer habe ich einen Stapel von Statistiken (Reputation, NumOfAnswers, NumOfVotes ... alle sind int). Ich möchte diese Statistiken abfragen, um die relevanten Benutzer zu erhalten.
%Vor%Ich bin jetzt daran interessiert, UserIDs basierend auf diesen Statistiken zu schneiden. Ich möchte alle Benutzer mit über 10K Ruf, ich möchte alle Benutzer mit weniger als 5 Antworten, etc. etc.
Ich hoffe, das hilft. Nochmals vielen Dank.
In CQL können Sie die Klausel WHERE
auf alle Spalten anwenden, nachdem Sie für sie Indizes erstellt haben (d. h. Sekundärindex). Andernfalls erhalten Sie den folgenden Fehler:
Leider muss die WHERE-Klausel selbst bei Sekundärindizes aufgrund der Leistung mindestens einen EQ für einen Sekundärindex durch CQL aufweisen Problem .
F: Warum muss immer mindestens ein EQ-Vergleich aktiviert sein? sekundäre Indizes?
A: Ungleichheiten auf Sekundärindizes sind immer getan im Speicher, also ohne mindestens einen EQ auf einem anderen Sekundärindex Sie werden jede Zeile in der Datenbank laden, was mit einer massiven Datenbank ist keine gute Idee. Also indem Sie mindestens einen EQ auf einem (sekundärer) Index, begrenzen Sie hoffentlich die Menge der Zeilen, die gelesen werden müssen Speicher auf eine überschaubare Größe. (Obwohl Sie natürlich immer noch bekommen können in Schwierigkeiten damit auch).
Wenn Sie also außer einem EQ-Vergleich noch etwas anderes haben, lädt er alle Zeilen, die "sonst mit Ihrer Abfrage übereinstimmen", und prüft, ob sie übereinstimmen. Was standardmäßig nicht erlaubt ist, da es "langsam sein könnte". (Im Prinzip indexieren Indizes nur "für die Gleichheit" und nicht für irgendetwas anderes wie & lt; und & gt; welche Indizes in einer relationalen Datenbank würden).
Beachten Sie Folgendes: Wenn Sie mehrere sekundäre EQ-Bedingungen für sekundäre Indizes haben, müssen Sie auch das Schlüsselwort ALLOW FILTERING
in Ihre Abfrage einfügen, sonst erhalten Sie
Cannot execute this query as it might involve data filtering and thus may have unpredictable performance. If you want to execute this query despite the performance unpredictability, use ALLOW FILTERING
Eine einfache Methode zur Umgehung besteht darin, eine Dummy-Spalte an Ihre Tabelle anzufügen, in der alle Zeilen den gleichen Wert für diese Spalte haben. In diesem Fall können Sie eine Bereichsabfrage nur für Ihre gewünschte Spalte durchführen. Stellen Sie sich vor, dass diese Art von Abfragen in einer NoSQL-Datenbank langsam sein / ein System verlangsamen können.
Beispiel
%Vor%Erstellen Sie sekundäre Indizes für ValueA und DummyValue:
%Vor% Führen Sie eine Bereichsabfrage für ValueA
mit DummyValue=0
:
Der wahrscheinlich flexibelste Weg, um mit diesem Szenario in Cassandra umzugehen, ist eine separate CF für jede Statistik, mit Sentinel-Werten als Schlüssel und dem stat-Wert im Spaltennamen, wie folgt:
%Vor%Nehmen wir also an, Ihr Stat ist NumAnswers und Ihre Benutzer-IDs sind Strings:
%Vor%Sie können also sehen, dass Ihre Schlüssel im Wesentlichen aus Buckets mit Werten bestehen, die so grob oder feinkörnig sein können, wie für Ihre Daten erforderlich, und Ihre Spalten sind Composites mit Wert + Benutzer-ID. Sie können nun Cassandra einen bekannten Schlüssel (oder Schlüsselsatz) für den groben Bereich übergeben, den Sie benötigen (Gleichheit), und dann eine Bereichsabfrage für die erste Komponente des Spaltennamens durchführen. Beachten Sie, dass Sie nicht die Benutzer-ID als Wert schreiben können, da dies verhindern würde, dass zwei Benutzer die gleiche Anzahl haben.
PRIMÄRSCHLÜSSEL (KeyA, KeyB) );
ERSTELLEN VON INDEX AUF Tabelle1 (WertA);
SELECT * FROM Tabelle1 WHERE WertA & gt; 3000;
Der Cassandra way
soll einen Partitionsschlüssel haben und diesen immer verwenden, mit einer Clusterspalte für ValueA
möglicherweise PRIMARY KEY ((KeyA, KeyB), ValueA)
und dann wie folgt verwenden:
select * from Table1 where KeyA='xx' and ValueA > 3000