2013-07-15 12 views
10

Jak mogę przeciągnąć zakres kolumn kompozytowych za pomocą CQL3?Iterowanie przez szeroki wiersz Cassandry z CQL3

rozważyć następujące:

CREATE TABLE Stuff (
    a int, 
    b text, 
    c text, 
    d text, 
    PRIMARY KEY (a,b,c) 
); 

W Cassandry co ten skutecznie działa to tworzy ColumnFamily z wierszy INTEGER (wartości a) oraz z CompositeColumns składających się z wartościami B i C, i ciągiem znaków „d ". Oczywiście to wszystko jest pokryte przez CQL3, więc będziemy myśleć, które wstawiamy do poszczególnych wierszy bazy danych ... ale dygresja.

I Rozważmy następujący zestaw wejść:

INSERT INTO Stuff (a,b,c,d) VALUES (1,'A','P','whatever0'); 
INSERT INTO Stuff (a,b,c,d) VALUES (1,'A','Q','whatever1'); 
INSERT INTO Stuff (a,b,c,d) VALUES (1,'A','R','whatever2'); 
INSERT INTO Stuff (a,b,c,d) VALUES (1,'A','S','whatever3'); 
INSERT INTO Stuff (a,b,c,d) VALUES (1,'A','T','whatever4'); 
INSERT INTO Stuff (a,b,c,d) VALUES (1,'B','P','whatever5'); 
INSERT INTO Stuff (a,b,c,d) VALUES (1,'B','Q','whatever6'); 
INSERT INTO Stuff (a,b,c,d) VALUES (1,'B','R','whatever7'); 
INSERT INTO Stuff (a,b,c,d) VALUES (1,'B','S','whatever8'); 
INSERT INTO Stuff (a,b,c,d) VALUES (1,'B','T','whatever9'); 

W moim obecnym przypadku użycia, chcę czytać wszystkie wartości rzeczy, n wartości w czasie. Jak mam to zrobic? Oto mój obecny odbioru za pomocą n=4:

SELECT * FROM Stuff WHERE a=1 LIMIT 4; 

i zgodnie z oczekiwaniami uzyskać:

a | b | c | d 
---+---+---+----------- 
1 | A | P | whatever0 
1 | A | Q | whatever1 
1 | A | R | whatever2 
1 | A | S | whatever3 

Kłopot że biegnę na to, jak mogę dostać następną 4? Oto moja próba:

SELECT * FROM Stuff WHERE a=1 AND b='A' AND c>'S' LIMIT 4; 

To nie działa, ponieważ mamy ograniczone do równego b „A” - co jest rozsądne rzeczą do zrobienia! Ale nie znalazłem nic w składni CQL3, która i tak pozwala mi kontynuować iterację. Chciałbym zrobić coś takiego:

SELECT * FROM Stuff WHERE a=1 AND {b,c} > {'A','S'} LIMIT 4; 

Jak osiągnąć pożądany wynik. Mianowicie, w jaki sposób mogę przywrócić CQL3:

a | b | c | d 
---+---+---+----------- 
1 | A | T | whatever0 
1 | B | P | whatever1 
1 | B | Q | whatever2 
1 | B | R | whatever3 
+0

Uwaga dla siebie: [ktoś, kto ma ten sam problem] (http://stackoverflow.com/q/16951532/348056). – JnBrymn

Odpowiedz

5

Auto stronicowania odbywa https://issues.apache.org/jira/browse/CASSANDRA-4415, to uwolnienie do Cassandry 2.0.1

+4

Dla mojego zrozumienia, Mam zainstalowany cassnadra 2.0.6 i przy użyciu cqlsh i próbowałem zrobić kwerendę wyboru na CF (który ma około 20K rekordów) bez podania limitu, wynik mojego zapytania wynosi 10K i wyświetla komunikat "** Domyślny LIMIT 10000 był używany. Określ własną klauzulę LIMIT, aby uzyskać więcej wyników. ** "..W takim razie, gdzie jest automatyczna paginacja, czy też coś złego robię/rozumiem. – Shri

0

Próbujesz zrobić coś na paginację w Cassandrze. CQL3 nie obsługuje tego. Powinieneś utworzyć kolumnę, która będzie odpowiednia dla porównania, tj. Dla operacji mniejszych niż większa niż operacje, a kolumna powinna tworzyć sekwencję zwiększania/zmniejszania. Rzeczywiście, jak jorgebg zauważył powyżej, łączenie b + c pasowałoby do tego.

4

Po przeczytaniu dokumentu CQL3 nie znalazłem sposobu na osiągnięcie pożądanego efektu.

Można jednak sfałszować pożądany efekt za pomocą szeregu zapytań CQL. Zastanów się, czy chcę przesyłać strony w powyższym modelu 4 na raz. Łatwo jest uzyskać pierwszy 4:

SELECT * FROM a = 1 LIMIT 4;

Jednak nie ma sposobu, aby uzyskać kolejne 4 w jednym zapytaniu. Ale mogę to zrobić w części.Ostatnia pozycja z powyższego zapytania jest

a | b | c | d 
---+---+---+----------- 
1 | A | S | whatever3 

Więc mogę wydać zapytanie do rozpocząć tutaj i dostać wszystko, aż do następnej wartości b:

select * from a = 1, gdzie B = 'A "i c>" S "LIMIT 4;

I w tym przypadku będę miał jeden wiersz CQL3:

a | b | c | d 
---+---+---+----------- 
1 | A | T | whatever4 

(obecnie, gdybym dostał 4 rzędy, chciałbym trafić limitu i chciałbym zacząć ponownie następnym razem z ostatnim . elementem tego zestawu Ale na razie mam tylko jeden wiersz) Tak więc, aby dostać resztę i iteracyjne od że punkt i uzyskać pozostałe 3 wiersze.

SELECT * FROM a = 1 WHERE b > 'A' LIMIT 3; 

a ja dalej z tego samego algorytmu dopóki nie zeskanowałem przyrostowo, o ile mi się podoba.

W powyższym przykładzie klucz podstawowy składa się z 3 elementów, co oznacza, że ​​pod CQL w Cassanderze nazwy kolumn to CompositeColumns z 2 elementami (... no w zasadzie, ale różnica tutaj nie ma znaczenia). A ponieważ obiekty CompositeColumns składają się z 2 elementów, musisz wykonać 2 kwerendy, tak jak to tutaj pokazałem. Generalnie jednak, jeśli KLUCZ GŁÓWNY jest z elementów n, trzeba będzie wykonać zapytania o numer n-1, aby sfałszować tabelę CQL (wiersz a.k.a Cassandra).


Aktualizacja: Rzeczywiście, CQL3 nie posiada kursor po stronie serwera (patrz rozdział „CQL3 paginacja” here), a jeśli chciał udawać, trzeba by użyć czegoś opisanego powyżej (przeczytaj dalej ten link, zobacz mój podstawowy pomysł opracowany przez autora postu).

Istnieje jednak JIRA issue dotyczące kursora po stronie serwera, który będzie dostępny w Cassandra 2 i który jest już obecny w Cassandra 2 Beta.

Istnieje również powiązany JIRA issue, który znacznie ułatwiłby implementację kursora po stronie klienta, o czym wspomniałem powyżej. Ale pozostaje nierozwiązany.


Aktualizacja 2: JIRA issue została naprawiona.

Można teraz zapytania przy użyciu krotny/wektor składni czym (C1, C2)> (1, 0)

+0

Nie polecam używania klauzuli LIMIT. Zamiast tego użyj kluczy podstawowych, być może za pomocą tabeli meta. Występują poważne spadki wydajności, które, jak przypuszczam, wynikają z natury rozproszonych baz danych - ponieważ wymagają uzgodnionego wysiłku w celu ustalenia, kiedy LIMIT zostanie osiągnięty, ktoś musi liczyć wszystkie wiersze przed zwróceniem wyniku. – omnibear

-1

select * from stuff where a = 1 and (b,c) > ('A','S') limit 4;

+0

Ogólnie rzecz biorąc, odpowiedzi są o wiele bardziej pomocne, jeśli zawierają wyjaśnienie, co kod ma zamiar zrobić i dlaczego rozwiązuje problem bez wprowadzania innych. (Ten post został zgłoszony przez co najmniej jednego użytkownika, prawdopodobnie dlatego, że uważał, że odpowiedź bez wyjaśnienia powinna zostać usunięta.) –

Powiązane problemy