2011-10-11 3 views
9

Je suis nouveau sur cassandra et hector donc j'essaie d'exécuter des requêtes cql mais le problème est que toutes les colonnes ne sont pas de type string alors comment dow j'exécute la requête "select * from users"?Comment utiliser les requêtes cql pour sortir différents types de données de cassandra avec le client java hector

Ma famille colonne ressemble à ceci:

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} 
]; 

J'utilise le code suivant pour exécuter la requête:

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(""); 
     } 
    } 

Mais à cause de la colonne « Annee_Naiss » avec la classe de validation longue que je peux » t obtenir la valeur. -je obtenir le résultat suivant en supposant qu'il n'y a qu'un seul enregistrement:

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

Si je change ma requête à ceci:

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

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

Que cela fonctionne.

Alors, comment puis-je faire cela avec une seule requête et si j'ai plus de types de données comme des booléens et des flottants dans les lignes d'une famille de colonnes?

Répondre

11

Vous spécifiez le type de valeur en tant que chaîne dans les CqlRows, de sorte que chaque valeur doit être une chaîne. Parce que vous voulez mélanger les types valeur, vous devez conserver les métadonnées de la colonne, mais également spécifier la classe de validation par défaut comme BytesType dans le schéma, puis utiliser ByteBuffer comme type dans CqlRows:

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

Ensuite, lors du traitement les valeurs, vous devrez convertir le type approprié, et au lieu de itérer à travers les colonnes, vous obtiendrez probablement la colonne spécifique par nom:

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

Bien sûr, les chaînes doivent être traitées différemment, en utilisant java .nio.charset.Charset:

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

Vous pouvez déterminer les types à partir des métadonnées de la colonne, mais je ne l'ai fait que via l'API Thrift (voir ColumnDef), donc je ne sais pas comment le faire via l'API Hector. Mais HColumn fournit une méthode getValueSerializer(), ce qui pourrait être un début.

+0

Salut libjack, merci pour votre réaction. Voulez-vous dire que cela n'est possible que si toutes les colonnes d'une famille de colonnes ont byteBuffer comme classe de validation par défaut? Ce n'est pas exactement ce que je veux, car lors de l'insertion de données dans Cassandra, la vérification des données valides ne fonctionne pas. Il serait possible d'insérer une chaîne dans la colonne birth_year. J'essaie votre code, mais la méthode 'getLong()' n'est pas reconnue. – Rubenski

+0

J'ai trouvé ce qui n'allait pas: "col.getValue(). GetLong()" Cela devrait être "column.getValueBytes(). GetLong()" Ma question précédente est résolue. Il est possible d'avoir plusieurs validation_classe dans une famille de colonnes. – Rubenski

+0

À droite, getLong() est une méthode sur ByteBuffer, alors getValue() ne retournera un ByteBuffer que si c'est le type spécifié pour HColumn: – libjack

Questions connexes