我在shell中创建了一个HBase表并添加了一些数据。在http://hbase.apache.org/book/dm.sort.html中写道,数据集首先按行键排序,然后按列排序。所以我在HBase Shell中尝试了一些东西:
hbase(main):013:0> put 'mytable', 'key1', 'cf:c', 'val'
0 row(s) in 0.0110 seconds
hbase(main):011:0> put 'mytable', 'key1', 'cf:d', 'val'
0 row(s) in 0.0060 seconds
hbase(main):012:0> put 'mytable', 'key1', 'cf:a', 'val'
0 row(s) in 0.0060 seconds
hbase(main):014:0> get 'mytable', 'key1'
COLUMN CELL
cf:a timestamp=1376468325426, value=val
cf:c timestamp=1376468328318, value=val
cf:d timestamp=1376468321642, value=val
3 row(s) in 0.0570 seconds
一切都很好看。我得到了正确的订单a - > c - > d喜欢预期。
现在我在Java中尝试使用Apache Pig:
pigServer.registerQuery("mytable_data = load 'hbase://mytable' using org.apache.pig.backend.hadoop.hbase.HBaseStorage('cf', '-loadKey true') as (rowkey:chararray, columncontent:map[]);");
printAlias("mytable_data"); // own function, which itereate over the keys
我得到了这个结果:
(key1,[c#val,d#val,a#val])
所以,现在订单是c - > d - >一个。这对我来说有点奇怪,难道不应该像HBase一样吗?对我来说,获得正确的顺序非常重要,因为我之后将地图转换为包,然后将其与其他表连接。如果两个输入都已排序,我可以使用合并连接而不将这些输入分类到数据集?!那么现在有人如何获得列的有序映射(或包)?
答案 0 :(得分:1)
您从根本上误解了某些内容 - HBaseStorage
后端将每个行加载为单个Tuple
。您已经告诉Pig将列族cf
加载为map:[]
,这正是Pig正在做的事情。引擎盖下的猪map
只是java.util.HashMap
,显然没有订单。
当前猪无法将map
转换为bag
,但这应该是一个简单的UDF来编写,禁止null
检查和其他样板,正文就像是
public DataBag exec(Tuple input) {
DataBag resultBag = bagFactory.newDefaultBag();
HashMap<String, Object> map = (HashMap<String, Object>) input.get(0);
for (Map.Entry<String, Object> entry : map) {
Tuple t = tupleFactory.newTuple();
t.append(entry.getKey());
t.append(entry.getValue().toString());
resultBag.add(t);
}
return resultBag;
}
然后,您可以生成bag{(k:chararray, v:chararray)}
,使用FLATTEN
按(k:chararray, v:chararray)
获取ORDER
和k
列表。
至于是否有办法将数据排序 - 通常没有。如果列族中的字段数量不是常数或字段不总是相同/已定义,则唯一的选项是
map
转换为bag
元组,然后排序LoadFunc
,其中包含一个表,一个列系列,并按扫描每个KeyValue
对发出一个元组。 HBase将确保排序并按照您在shell中看到的排序顺序为您提供数据,但请注意,订单仅在加载时保证。你申请的任何进一步转型都会破坏这种转变。