2012-07-31 59 views
2

我們有cassandra列家族。每行有 有多列。列有名稱,但值爲空。 如果我們有5-10行鍵,我們如何找到出現在所有這些鍵中的列名。 例如相交cassandra行

row1: php, programming, accounting 
row2: php, bookkeeping, accounting 
row3: php, accounting 

必須返回:

result: php, accounting 

筆記中,我們不能輕易地加載整個一行到內存中,因爲它可能包含1M +列 解決方案並不需要快。

回答

1

爲了做好幾行的交集,我們需要先交叉它們中的兩個,然後再與第三個交叉結果等等。

看起來像cassandra我們可以通過列名查詢數據,這是相對較快的操作。

所以我們首先得到10k行的Column Slice。列名列表(在PHP Cassa中 - 把它們放在數組中)。然後選擇第二行的那些。

代碼可能看起來像這樣:

$x = $cf->get($first_key, <some column slice>); 

$column_names = array(); 
foreach(array_keys($x) as $k) 
    $column_names[] = $k; 

$result = $cf->get($second_key, $column_slice = null, $column_names); 

// write result somewhere, and proceed with next slice 
+1

這是事實,但nosql的一個很好的經驗法則是根據您的讀寫模式設計您的數據。最好嘗試使用超級列創建一個手動索引,這些列會將您的標記(如php會計)作爲第一級列和行標記,並將這些標記作爲第二級標記。但是,這可能不會爲你當前的問題提供一個解決方案:P我想說 – Tamil 2012-08-03 07:12:55

+0

你的想法與超級列是輝煌的。 唯一的缺點我看我的情況是,在插入之後,我需要做第二遍,所以我可以統計每個超級列。 – Nick 2012-08-03 22:08:53

+0

但是,我可以在單行上使用計數器,而不是超級列 - 每個標記的計數器。然後我增加它們,最後再做一遍,以便找到哪些計數器有相交的行數。 – Nick 2012-08-03 22:16:28

0

您對列的名稱進行了排序,您可以爲每行創建一個迭代器(此迭代器一次加載部分日期,例如10k列)。現在將每個迭代器放入一個優先級隊列中(通過下一個列名稱)。如果您將具有相同列名稱的迭代器的k倍用於隊列,則這是所有行之間的通用名稱,在另一種情況下,我們將移動到下一個元素並將迭代器返回到隊列。

0

你可以使用一個Hadoop的map/reduce任務如下:

  • 地圖輸出鍵=列名

  • 地圖輸出值=行鍵

  • 減速計數的行鍵每列和輸出列名稱&計數到具有以下架構的CF:

    鍵:[列名] { Count:[count] }

  • 然後,您可以按相反順序從此CF中查詢計數。第一個記錄將是最大值,因此您可以保持迭代,直到最大值爲<。這將是你的交集。

+0

有趣的方法,但我不知道Hadoop的呢。不管怎麼說,還是要謝謝你。 – Nick 2012-08-02 20:51:53

+0

@Nick除了樣板,這可能是M/R作業中的20行代碼,如果您計劃使用Cassandra,那麼Hadoop更值得您的努力。您也可以在Pig或Hive中輕鬆完成此操作,無需手動編寫M/R。 – 2012-08-02 21:47:45

+0

對,Hadoop在我的學習清單中。 – Nick 2012-08-03 22:17:56