2013-10-15 223 views
4
使用威嚇客戶端使用組合密鑰的第一組分行

我使用在rowkey複合數據類型,列族是如下獲取卡桑德拉

create column family CompositeTest 
with comparator = 'UTF8Type' 
and key_validation_class = 'CompositeType(UTF8Type,UTF8Type)' 
and default_validation_class = 'UTF8Type'; 

此列家族如下面所述的樣品數據,

RowKey: s2:2222222 
=> (column=param1, value=value1 
=> (column=param2, value=value2 
=> (column=param3, value=value3 
------------------- 
RowKey: s2:3333333 
=> (column=param1, value=value1 
=> (column=param2, value=value2 
=> (column=param3, value=value3 
------------------- 
RowKey: s2:1111111 
=> (column=param1, value=value1 
=> (column=param2, value=value2 
=> (column=param3, value=value3 
------------------- 
RowKey: s1:3333333 
=> (column=param1, value=value1 
=> (column=param2, value=value2 
=> (column=param3, value=value3 
------------------- 
RowKey: s1:2222222 
=> (column=param1, value=value1 
=> (column=param2, value=value2 
=> (column=param3, value=value3 
------------------- 
RowKey: s1:1111111 
=> (column=param1, value=value1 
=> (column=param2, value=value2 
=> (column=param3, value=value3 

我想獲得行密鑰的第一個組件是「s1」的所有行。是否有可能使用Hector客戶端?如果不是,那麼cassandra客戶端可能是哪個?

我用下面的代碼試過,但其沒有工作,

Composite start = new Composite(); 
     start.addComponent(0, "s1", ComponentEquality.EQUAL); 

     Composite end = new Composite(); 
     end.addComponent(0, "s1", ComponentEquality.GREATER_THAN_EQUAL); 

     RangeSlicesQuery<Composite, String, String> rangeSlicesQuery = HFactory.createRangeSlicesQuery(keyspace, new CompositeSerializer(), StringSerializer.get(), StringSerializer.get()); 
     rangeSlicesQuery.setKeys(start, end); 
     rangeSlicesQuery.setRange("param1", "param3", false, 100); 
     rangeSlicesQuery.setColumnFamily("CompositeTest"); 
     rangeSlicesQuery.setRowCount(11); 
     QueryResult<OrderedRows<Composite, String, String>> queryResult = rangeSlicesQuery.execute(); 

     Rows<Composite, String, String> rows = queryResult.get(); 
     Iterator<Row<Composite, String, String>> rowsIterator = rows.iterator(); 

在此先感謝...

+1

Hector客戶端和Astyanax客戶端都可以這樣做。 –

+2

如果可能,那麼請你分享我如何使用Hector來做到這一點? –

回答

1

問題是您正在嘗試在行鍵上執行切片。 如果您在Cassandra中使用隨機分區程序(例如RandomPartitioner或Murmur3Partitioner),則完全不可能。如果您正在使用訂單保留分區程序,這可能是可能的(但我從未嘗試過)。在你的情況下,應該是一個不幸運的CompositeKeyPartitioner,因此你必須自己編寫它。然後,您還應該根據您的數據計算權限令牌來配置羣集。如你所見,這不是最簡單的方法。

但是,你可以這樣做,如果你只是把複合值放在列名中而不是鍵。 可以定義你這樣的方式CF卡:

create column family CompositeTest 
    with comparator = 'CompositeType(UTF8Type,UTF8Type)' 
    and key_validation_class = 'UTF8Type' 
    and default_validation_class = 'UTF8Type'; 

和數據存儲,如:

RowKey: s2 
=> (column=2222222:param1, value=value1 
=> (column=2222222:param2, value=value2 
=> (column=2222222:param3, value=value3 
=> (column=3333333:param1, value=value1 
=> (column=3333333:param2, value=value2 
=> (column=3333333:param3, value=value3 
=> (column=1111111:param1, value=value1 
=> (column=1111111:param2, value=value2 
=> (column=1111111:param3, value=value3 
------------------- 
RowKey: s1: 
=> (column=3333333:param1, value=value1 
=> (column=3333333:param2, value=value2 
=> (column=3333333:param3, value=value3 
=> (column=2222222:param1, value=value1 
=> (column=2222222:param2, value=value2 
=> (column=2222222:param3, value=value3 
=> (column=1111111:param1, value=value1 
=> (column=1111111:param2, value=value2 
=> (column=1111111:param3, value=value3 

通過這樣的結構,你認爲它很容易查詢,那麼你可以隨時在列切名稱以僅選擇您想要的時間間隔內的那些列。

+0

即使使用OPP(我不建議使用這是一種專家模式功能),您仍然無法僅針對組合行鍵的一部分執行RangeSlicesQuery。你必須對整個行鍵進行操作,即得到完整行鍵A到完整行鍵B之間的所有鍵。 – Aaronontheweb

+1

你爲什麼這麼說? 正如我所說的,你應該有一個可以正確排序組合值的分區器,但這與列名稱的邏輯非常相似。 的確,應該只是使用值ComponentEquality.GREATER_THAN_EQUAL或ComponentEquality.EQUAL來設置組合鍵的空白部分,具體取決於鍵是開始還是結束。 它的一部分,這是完全可能的..但肯定不建議。 ;) – cesare

+1

現在我想到了,你是對的。你可以做到這一點。 – Aaronontheweb

2

這是不可能的卡桑德拉使用任何客戶端。雖然行鍵對您來說是一個複合對象,但應用程序開發人員在Cassandra本身中的行鍵是一個單獨的字節數組,它作爲單個原子值存儲在Cassandra的SSTable中。

含義,你只能查詢一排整個鍵,不只是一個重要的組成部分。否則,您將不得不掃描整個專欄系列,直到找到匹配項 - 這將非常昂貴。這就是說,如果您確實需要能夠使用行鍵的一部分查詢列族中的行,那麼我強烈建議爲這些關鍵部分創建單獨的索引列族。這將允許您使用標準鍵/列查找來查找原始數據列族中符合條件的所有行。