2014-05-13 8 views
7

Quindi, il mio problema è stato originale utilizzando la funzione di memoria() alla pagina attraverso un grande insieme di dati in Cassandra 1.2.9, come spiegato e risposto qui: Paging large resultsets in Cassandra with CQL3 with varchar keysPaging gruppi di risultati di Cassandra con chiavi primarie composte - rinunciare a righe

La risposta accettata ha ottenuto la selezione che funziona con token e dimensioni del blocco, ma si è manifestato un altro problema.

Il mio tavolo si presenta così in cqlsh:

key   | column1    | value 
---------------+-----------------------+------- 
    85.166.4.140 |  county_finnmark |  4 
    85.166.4.140 |  county_id_20020 |  4 
    85.166.4.140 |  municipality_alta |  2 
    85.166.4.140 | municipality_id_20441 |  2 
93.89.124.241 |  county_hedmark | 24 
93.89.124.241 |  county_id_20005 | 24 

La chiave primaria è un composto di chiave e column1. Nel CLI, gli stessi dati è simile al seguente:

get ip['85.166.4.140']; 
=> (counter=county_finnmark, value=4) 
=> (counter=county_id_20020, value=4) 
=> (counter=municipality_alta, value=2) 
=> (counter=municipality_id_20441, value=2) 
Returned 4 results. 

Il problema

Quando si utilizza CQL con un limite di vale a dire 100, i risultati restituiti possono fermarsi nel bel mezzo di un record, in questo modo:

key   | column1    | value 
---------------+-----------------------+------- 
    85.166.4.140 |  county_finnmark |  4 
    85.166.4.140 |  county_id_20020 |  4 

lasciando questi per "file" (colonne) su:

85.166.4.140 |  municipality_alta |  2 
    85.166.4.140 | municipality_id_20441 |  2 

Ora, quando uso la funzione di token() per la pagina successiva, come, queste due righe vengono saltati:

select * from ip where token(key) > token('85.166.4.140') limit 10; 

Risultato:

key   | column1    | value 
---------------+------------------------+------- 
93.89.124.241 |   county_hedmark | 24 
93.89.124.241 |  county_id_20005 | 24 
95.169.53.204 |  county_id_20006 |  2 
95.169.53.204 |   county_oppland |  2 

Quindi, nessuna traccia degli ultimi due risultati da il precedente indirizzo IP.

Domanda

Come posso usare per memoria() per il paging senza saltare sopra le righe CQL? Qualcosa di simile:

select * from ip where token(key) > token(key:column1) limit 10; 

risposta

5

Ok, quindi ho usato le informazioni in questo post per trovare una soluzione: http://www.datastax.com/dev/blog/cql3-table-support-in-hadoop-pig-and-hive (sezione "CQL3 impaginazione").

Innanzitutto, eseguire questa CQL:

select * from ip limit 5000; 

Dall'ultima riga del risultato, ottengo la chiave (ossia '85 .166.4.140') e il valore da column1 (cioè 'county_id_20020').

Poi ho creare una dichiarazione preparata la valutazione di

select * from ip where token(key) = token('85.166.4.140') and column1 > 'county_id_20020' ALLOW FILTERING; 

(sto cercando di indovinare che avrebbe funzionato anche senza utilizzare la funzione di() di token, come il controllo è ora pari :)

select * from ip where key = '85.166.4.140' and column1 > 'county_id_20020' ALLOW FILTERING; 

Il set di risultati contiene ora le restanti righe X (colonne) per questo IP. Il metodo restituisce quindi tutte le righe e la chiamata successiva al metodo include l'ultima chiave utilizzata ('85 .166.4.140 ').Con questa chiave, posso eseguire il seguente selezionare:

select * from ip where token(key) > token('85.166.4.140') limit 5000; 

che mi dà i prossimi 5000 righe da (e compresa) il primo IP dopo '85 .166.4.140' .

Ora nessuna colonna è persa nel paging.

UPDATE

Cassandra 2.0 introdotto paginazione automatica, gestita dal cliente. Maggiori informazioni qui: http://www.datastax.com/dev/blog/client-side-improvements-in-cassandra-2-0

(si noti che setFetchSize è facoltativa e non necessaria per il paging al lavoro)

Problemi correlati