我们有cassandra列族。每一行都有多列。列有名称,但值为空。如果我们有5-10个行键,我们如何找到出现在所有这些键中的列名。例如
row1: php, programming, accounting
row2: php, bookkeeping, accounting
row3: php, accounting
必须返回:
result: php, accounting
注意,我们不能轻易地将整行加载到内存中,因为它可能包含1M以上的列解决方案不需要很快。
为了进行几行的相交,我们需要先将其中两行相交,然后将结果与第三行相交,依此类推
看起来在cassandra中,我们可以通过列名查询数据,这是一个相对快速的操作。
所以我们首先得到10k行的列切片。制作列名列表(在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
对列名进行排序,可以为每行创建一个迭代器(该迭代器一次加载部分日期,例如10k列)。现在将每个迭代器放入一个优先级队列(按下一个列名)。如果您将具有相同列名的迭代器的k倍作为队列,这是所有行之间的通用名称,在另一种情况下,我们移动到下一个元素并将迭代器返回到队列。
您可以使用Hadoop映射/减少作业,如下所示:
-
映射输出键=列名
-
映射输出值=行键
-
Reducer对每列的行键进行计数,并输出列名&计数到具有以下模式的CF:
关键字:[列名]{计数:[Count]}
-
然后,您可以按相反的顺序从该CF查询计数。第一条记录将是最大值,因此您可以继续迭代,直到值<max。这将是你的十字路口。