2011-10-11 26 views
9

我是cassandra和hector的新手,所以我試圖執行cql查詢,但問題是並非所有列都是字符串類型,所以如何我執行查詢「select * from users」?如何使用cql查詢從卡桑德拉用java客戶端獲取不同的數據類型hector

我列族是這樣的:

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

我用下面的代碼來執行查詢:

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

因爲驗證類的「birth_year」列,但長期我可以」沒有價值。 我得到以下結果假設只有一個記錄:

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

如果我改變我的查詢到這一點:

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

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

比它的工作原理。

那麼我怎樣才能做到這一點只有一個查詢,以及如果我有更多的數據類型像布爾家族的行布爾值和浮點數?

回答

11

您在CqlRows中將值類型指定爲字符串,因此每個值都應該是一個字符串。因爲你想混值類型,你應該保持列元,而且還可以指定默認的驗證類,如架構中BytesType然後用字節緩衝區作爲CqlRows類型:

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

然後,當處理價值觀,你將不得不轉換爲相應的類型,而不是通過列迭代,你可能會通過名稱獲得特定列:

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

當然,字符串也有不同的處理,用java .nio.charset.Charset:

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

您可以從列元數據中確定類型,但我只通過Thrift API(請參閱ColumnDef)完成此操作,所以不知道如何通過Hector API執行此操作。但HColumn確實提供了一個getValueSerializer()方法,所以這可能是一個開始。

+0

嗨libjack,謝謝你的反應。 您的意思是說,只有在列家族中的所有列都將byteBuffer作爲默認驗證類時纔有可能?這並不是我想要的,因爲將數據插入cassandra時,有效數據的檢查不起作用。可以在列birth_year中插入一個字符串。 我正在嘗試您的代碼,但getLong()方法無法識別。 – Rubenski

+0

我發現什麼是錯的whith:「col.getValue()。getLong()」 它應該是「column.getValueBytes()。getLong()」 我的上一個問題已解決。在列族中可以有多個validation_classe。 – Rubenski

+0

對,getLong()是ByteBuffer的一種方法,所以getValue()只會返回一個ByteBuffer,如果這是爲HColumn指定的類型: – libjack