2011-10-11 12 views
9

Jestem nowy dla kassandra i hector, więc staram się wykonywać kwerendy cql, ale problem polega na tym, że nie wszystkie kolumny są typu ciąg, więc jak dow I wykonuję zapytanie "wybierz * od użytkowników"?Jak korzystać z zapytań CQL, aby uzyskać różne typy danych z kassandra z klientem java klienta

Moja rodzina kolumna wygląda następująco:

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

używam następujący kod do wykonania zapytania:

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

Ale ze względu na „birth_year” kolumny z klasy walidacji Długi mogę” t uzyskać wartość. uzyskać następujący wynik przy założeniu, że istnieje tylko jeden rekord:

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

Jeśli zmienię moje zapytanie do tego:

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

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

Niż to działa.

Jak mogę to zrobić za pomocą tylko jednego zapytania i co jeśli mam więcej typów danych, takich jak wartości logiczne i zmiennoprzecinkowe w wierszach rodziny kolumn?

Odpowiedz

11

Typ wartości określony jako String w CqlRows, więc każda wartość ma być ciągiem. Ponieważ chcesz mieszać typów wartości, należy zachować metadane kolumny, ale również określić domyślną klasę walidacji jako BytesType w schemacie, a następnie użyć ByteBuffer jako typ w CqlRows:

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

Następnie podczas przetwarzania wartości, trzeba będzie konwertować do odpowiedniego typu, a zamiast iteracja kolumn, będzie prawdopodobnie uzyskać konkretną kolumnę o nazwie:

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

oczywiście Struny muszą być traktowane w różny sposób, przy użyciu języka Java .nio.charset.Charset:

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

Można określić typy z metadanych kolumny, ale zrobiłem to tylko za pośrednictwem interfejsu Thrift API (patrz ColumnDef), więc nie wiem, jak to zrobić za pomocą interfejsu API Hectora. Ale HColumn dostarcza metodę getValueSerializer(), więc może to być początek.

+0

Witaj, libjack, dziękuję za reakcję. Czy to oznacza, że ​​jest to możliwe tylko wtedy, gdy wszystkie kolumny w rodzinie kolumn mają bajtBuffer jako domyślną klasę sprawdzania poprawności? To nie jest dokładnie to, czego chcę, ponieważ podczas wstawiania danych do Kasandra sprawdzenie poprawnych danych nie działa. Byłoby możliwe wstawienie ciągu w kolumnie birth_year. Próbuję Twojego kodu, ale metoda "getLong()" nie jest rozpoznawana. – Rubenski

+0

Znalazłem, co było źle whith: "col.getValue(). GetLong()" Powinien to być "column.getValueBytes(). GetLong()" Moje poprzednie pytanie zostało rozwiązane. W rodzinie kolumn można mieć wiele klas validation_classe. – Rubenski

+0

Dobrze, getLong() to metoda na ByteBuffer, więc getValue() zwróci tylko ByteBuffer, jeśli jest to typ określony dla HColumn: – libjack

Powiązane problemy