2011-10-11 14 views
9

Soy nuevo en cassandra y hector, así que estoy tratando de ejecutar consultas cql pero el problema es que no todas las columnas son de tipo cadena, ¿cómo? ¿Ejecutaré la consulta "select * from users"?Cómo usar las consultas cql para obtener diferentes tipos de datos de cassandra con el cliente de java hector

Mi familia columna tiene el siguiente aspecto:

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

utilizo el siguiente código para ejecutar la consulta:

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

Pero debido a la columna 'birth_year' con la clase de validación tiempo puedo' obtener el valor me sale el siguiente resultado suponiendo que hay un solo registro:

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

Si cambio de consulta a este:

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

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

De lo que funciona.

Entonces, ¿cómo puedo hacer esto con una sola consulta y qué ocurre si tengo más tipos de datos como booleanos y flotantes en las filas de una familia de columnas?

Respuesta

11

Especifique el tipo de valor como Cadena en CqlRows, por lo que se espera que cada valor sea una cadena. Debido a que usted quiere mezclar tipos de valor, debe mantener los metadatos de columna, sino también especificar la clase de validación por defecto como BytesType en el esquema y luego usar ByteBuffer como el tipo de CqlRows:

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

Entonces, cuando se procesan los valores, se tendrán que convertir al tipo adecuado, y en vez de iteración a través de las columnas, es probable que obtener la columna específica por su nombre:

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

por supuesto, las cadenas tienen que ser manejados de manera diferente, utilizando java .nio.charset.Charset:

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

Puede determinar los tipos a partir de los metadatos Columna, pero solo he hecho esto a través de la API Thrift (vea ColumnDef), por lo que no estoy seguro de cómo hacerlo a través de Hector API. Pero HColumn proporciona un método getValueSerializer(), por lo que podría ser un comienzo.

+0

Hola, libjack, gracias por tu reacción. ¿Quiere decir que solo es posible si todas las columnas de una familia de columnas tienen byteBuffer como clase de validación predeterminada? Eso no es lo que quiero, porque cuando insertas datos en cassandra, la verificación de datos válidos no funciona. Sería posible insertar una cadena en la columna birth_year. Estoy intentando su código, pero el método 'getLong()' no se reconoce. – Rubenski

+0

Encontré lo que estaba mal con: "col.getValue(). GetLong()" Debe ser "column.getValueBytes(). GetLong()" Mi pregunta anterior está resuelta. Es posible tener múltiples validation_classe en una familia de columnas. – Rubenski

+0

Derecha, getLong() es un método en ByteBuffer, por lo que getValue() solo devolverá un ByteBuffer si ese es el tipo especificado para HColumn: – libjack

Cuestiones relacionadas