我正在试图弄清楚如何在Hbase中执行等效的Oracle's LEAD and LAG或其他一些可以解决我的问题的模式。我可以编写一个MapReduce程序,可以很容易地完成这项工作,但我希望能够利用数据已经按照我需要的方式进行排序这一事实。
我的问题如下:我有一个rowkey和一个看起来像这样的值:
(employee name + timestamp) => data:salary
因此,一些示例数据可能是:
miller, bob;2010-01-14 => data:salary=90000
miller, bob;2010-11-04 => data:salary=102000
miller, bob;2011-12-03 => data:salary=107000
monty, fred;2010-04-10 => data:salary=19000
monty, fred;2011-09-09 => data:salary=24000
我想做的是计算薪水的变化,记录。我想将上述数据转换为记录之间的差异:
miller, bob;2010-01-14 => data:salarydiff=90000
miller, bob;2010-11-04 => data:salarydiff=12000
miller, bob;2011-12-03 => data:salarydiff=5000
monty, fred;2010-04-10 => data:salarydiff=19000
monty, fred;2011-09-09 => data:salarydiff=5000
如果有必要,我可以更改rowkey策略。
答案 0 :(得分:1)
我要做的是更改密钥以便时间戳下降(新工资优先)
miller, bob;2011-12-03 => data:salary=107000
miller, bob;2010-11-04 => data:salary=102000
miller, bob;2010-01-14 => data:salary=90000
现在,您可以执行一个扫描表格的简单地图作业。然后在地图中创建一个新的扫描到当前键。 Scan.next获取上一个薪水,计算差异并将其存储在当前行键的新列中 基本上在mapper类(继承TableMapper的类)中,您覆盖setup方法并获取配置
@Override
protected void setup(Mapper.Context context) throws IOException,InterruptedException {
Configuration config = context.getConfiguration();
table = new HTable(config,<Table Name>);
}
然后在地图内部从行参数中提取行键,创建新的扫描并继续,如上所述
在大多数情况下,下一条记录将位于同一区域 - 有时它可能会转到另一个区域服务器