2011-10-11 7 views
9

Sono nuovo a cassandra e hector quindi sto provando a eseguire query cql ma il problema è che non tutte le colonne sono di tipo stringa, quindi come dow eseguo la query "select * from users"?Come utilizzare le query cql per ottenere diversi tipi di dati da cassandra con java client hector

mia famiglia colonna assomiglia a questo:

UPDATE COLUMN FAMILY users 
WITH comparator = UTF8Type 
AND key_validation_class=UTF8Type 
AND column_metadata = [ 
{column_name: full_name, validation_class: UTF8Type} 
{column_name: email, validation_class: UTF8Type} 
{column_name: state, validation_class: UTF8Type, index_type: KEYS} 
{column_name: gender, validation_class: UTF8Type} 
{column_name: birth_year, validation_class: LongType, index_type: KEYS} 
{column_name: education, validation_class: UTF8Type} 
]; 

Io uso il seguente codice per eseguire la query:

CqlQuery<String, String, String> cqlQuery = new CqlQuery<String, String, String>(Keyspace,stringSerializer,stringSerializer,stringSerializer); 

    cqlQuery.setQuery("select * from users"); 

    QueryResult<CqlRows<String, String, String>> result = cqlQuery.execute(); 


    if (result != null && result.get() != null) { 
     List<Row<String, String, String>> list = result.get().getList(); 
     for (Row row : list) { 
      System.out.println("."); 
      List columns = row.getColumnSlice().getColumns(); 
      for (Iterator iterator = columns.iterator(); iterator.hasNext();) { 
       HColumn column = (HColumn) iterator.next(); 
       System.out.print(column.getName() + ":" + column.getValue() 
         + "\t"); 
      } 
      System.out.println(""); 
     } 
    } 

Ma a causa della colonna 'birth_year' con classe di convalida tempo posso' t ottenere il valore. ottengo il seguente risultato supponendo che ci sia solo un record:

KEY:Carl birth_year: 'strange chars?' full_name:Carl Smith gender:M eduction:electrician state:LA 

Se cambio la mia domanda a questo:

CqlQuery<String, String, Long> cqlQuery = new CqlQuery<String, String, Long> 
TutorialBase.tutorialKeyspace, stringSerializer, stringSerializer, longSerializer); 

    cqlQuery.setQuery("select birth_year from users"); 

Than funziona.

Quindi, come posso farlo con una sola query e se ho più tipi di dati come booleani e float nelle righe di una famiglia di colonne?

risposta

11

Si specifica il tipo di valore come Stringa in CqlRows, quindi ogni valore dovrebbe essere una stringa. Perché si vuole mescolare tipi di valore, si dovrebbe tenere i metadati della colonna, ma anche specificare la classe di validazione di default come BytesType nello schema e quindi utilizzare ByteBuffer come tipo in CqlRows:

QueryResult<CqlRows<String, String, ByteBuffer>> result = cqlQuery.execute(); 

Poi, durante l'elaborazione i valori, si dovrà convertire il tipo appropriato, e invece di iterazione attraverso le colonne, probabilmente otterrete la colonna specifica per nome:

ColumnSlice<String, ByteBuffer> slice = row.getColumnSlice(); 
HColumn<String,ByteBuffer> col = slice.getColumnByName("birth_year"); 
System.out.println(" birth_year: " + col.getValue().getLong()); 

Naturalmente, le stringhe devono essere gestite in modo diverso, utilizzando Java .nio.charset.Charset:

Charset.defaultCharset().decode(col.getValue()).toString() 

È possibile determinare i tipi dai meta-dati Colonna, ma l'ho fatto solo tramite l'API di Thrift (vedere ColumnDef), quindi non sono sicuro di come farlo tramite l'API Hector. Ma HColumn fornisce un metodo getValueSerializer(), quindi potrebbe essere un inizio.

+0

Hi libjack, grazie per la vostra reazione. Vuoi dire che è possibile solo se tutte le colonne di una famiglia di colonne hanno byteBuffer come classe di convalida predefinita? Questo non è esattamente quello che voglio, perché quando si inseriscono dati in cassandra il controllo dei dati validi non funziona. Sarebbe possibile inserire una stringa nella colonna birth_year. Sto provando il codice, ma il metodo 'getLong()' non è riconosciuto. – Rubenski

+0

Ho trovato cosa non andava con "col.getValue(). GetLong()" Dovrebbe essere "column.getValueBytes(). GetLong()" La mia domanda precedente è stata risolta. È possibile avere più validation_classe in una famiglia di colonne. – Rubenski

+0

Right, getLong() è un metodo su ByteBuffer, quindi getValue() restituirà solo un ByteBuffer se questo è il tipo specificato per HColumn: – libjack

Problemi correlati