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