HBase中的排序顺序与Java中的Pig/Piglatin

HBase中的排序顺序与Java中的Pig/Piglatin,java,hadoop,hbase,apache-pig,Java,Hadoop,Hbase,Apache Pig,我在shell中创建了一个HBase表并添加了一些数据。在中,数据集首先按行键排序,然后按列排序。所以我在HBase外壳中尝试了一些东西: 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(

我在shell中创建了一个HBase表并添加了一些数据。在中,数据集首先按行键排序,然后按列排序。所以我在HBase外壳中尝试了一些东西:

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->a。这对我来说似乎有点奇怪,它不应该和HBase中的一样吗?对我来说,获得正确的顺序很重要,因为我会将地图转换成一个包,然后将其与其他表连接起来。如果两个输入都已排序,我可以使用合并联接,而无需将它们排序到数据集?!那么现在有人知道如何获得列的排序图(或包)了吗

您从根本上误解了什么--
hbastorage
后端将每一行作为一个
元组加载。您已经告诉Pig将列族
cf
作为
map:[]
加载,这正是Pig所做的。引擎盖下的Pig
map
只是一个
java.util.HashMap
,显然没有顺序

在pig中,目前没有办法将
映射
转换为
,但这应该是一个很容易编写的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;
}
公共数据库执行(元组输入){ DataBag resultBag=bagFactory.newDefaultBag(); HashMap=(HashMap)input.get(0); for(Map.Entry:Map){ Tuple t=tupleFactory.newTuple(); t、 追加(entry.getKey()); t、 追加(entry.getValue().toString()); 结果添加(t); } 返回结果包; }
这样,您就可以生成一个
bag{(k:chararray,v:chararray)}
,使用
FLATTEN
来获得
(k:chararray,v:chararray)
ORDER
的列表

至于是否有方法对数据进行排序,通常是否定的。如果列族中的字段数量不是恒定的,或者字段不总是相同/定义的,那么您唯一的选择是

  • 映射
    转换为元组的
    ,然后进行排序
  • 或者编写一个自定义的
    LoadFunc
    ,它接受一个表、一个列族,并为每个
    KeyValue
    扫描对发出一个元组。HBase将确保排序,并按照您在shell中看到的排序顺序为您提供数据,但请注意,只有在加载时才能保证顺序。您应用的任何进一步转换都会破坏这一点

它是按字母顺序排序还是按插入顺序排序?输出似乎是按插入顺序排序哇,这有点不清楚。那么在您想要的输出中,映射值需要按字母顺序排序?为什么不直接对UDF中的值进行排序呢?我的想法是连接输出并尝试改进连接。因此,我尝试了合并联接,并想知道为什么输出没有排序。当然,我可以自己对输出进行排序,但这需要时间。如果有办法对数据进行排序,速度会更快。