1

嗨,

Hbase 允许列族在不同的行中具有不同的限定符。在我的情况下,列族具有以下规范

abc[cnt] # where cnt is an integer that can be any positive integer

我想要实现的是从不同的列族中获取所有数据,前提是所描述的限定符(在不同的列族中)的值匹配。

为了缩小扫描范围,我只需添加查询所需的这两个系列。但这是我现在所能得到的。

我已经使用 SingleColumnValueFilter 实现了相同的行为,但是预先知道了限定符。但是对于这个,限定符可以是abc1abc2 ...选项太多,因此 SingleColumnValueFilter 太多。

然后我尝试使用 ValueFilter,但这个过滤器只返回那些与值匹配的列,因此是错误的列族。

您能想出任何方法来实现我的目标,在列族中动态创建的限定符中查询值并返回列族和另一个列族的内容(如创建扫描时指定的那样)?最好只查询一次。

提前感谢您的任何意见。

更新:(如评论中讨论的澄清)

以更图形化的方式,一行可能有以下内容:

colfam1:aaa
colfam1:aab
colfam1:aac
colfam2:abc1
colfam2:abc2

而如果colfam2的任何值具有例如值x,我想获得colfam1的所有家庭,关于colfam2:abc [cnt]是动态创建的,而cnt是任何正整数

4

1 回答 1

3

我看到了两种方法:客户端过滤或服务器端过滤。

客户端过滤更直接。Scan 仅添加两个系列“ colfam1”和“ colfam2”。然后,对于Result您从 中获得的每个scanner.next(),您必须根据“ colfam2”中的限定词进行过滤。

byte[] queryValue = Bytes.toBytes("x");
Scan scan = new Scan();
scan.addFamily(Bytes.toBytes("colfam1");
scan.addFamily(Bytes.toBytes("colfam2");
ResultScanner scanner = myTable.getScanner(scan);
Result res;
while((res = scanner.next()) != null) {
   NavigableMap<byte[],byte[]> colfam2 = res.getFamilyMap(Bytes.toBytes("colfam2"));
   boolean foundQueryValue = false;
   SearchForQueryValue: while(!colfam2.isEmpty()) {
       Entry<byte[], byte[]> cell = colfam2.pollFirstEntry();
       if( Bytes.equals(cell.getValue(), queryValue) ) {
           foundQueryValue = true;
           break SearchForQueryValue;
       }
   }
   if(foundQueryValue) {
       NavigableMap<byte[],byte[]> colfam1 = res.getFamilyMap(Bytes.toBytes("colfam1"));
       LinkedList<KeyValue> listKV = new LinkedList<KeyValue>();
       while(!colfam1.isEmpty()) {
           Entry<byte[], byte[]> cell = colfam1.pollFirstEntry();
           listKV.add(new KeyValue(res.getRow(), Bytes.toBytes("colfam1"), cell.getKey(), cell.getValue()); 
       }
       Result filteredResult = new Result(listKV);
   }
}

(此代码未经测试)

最后filteredResult就是你想要的。这种方法并不优雅,如果您在这些系列中有大量数据,也可能会给您带来性能问题。如果“colfam1”有很多数据,如果值“x”不在“colfam2”的限定符中,则最终不会被使用,您不想将其传输到客户端。

服务器端过滤。这需要您实现自己的 Filter 类。我相信您不能使用提供的过滤器类型来执行此操作。实现您自己的过滤器需要一些工作,您还需要将其编译为 .jar 并使其可用于所有 RegionServer。但是,它可以帮助您避免徒劳地发送“colfam1”的大量数据。向您展示如何自定义实现过滤器对我来说工作量太大,因此我建议您阅读一本好书(例如HBase: The Definitive Guide)。但是,过滤器代码看起来很像我向您展示的客户端过滤,所以这已经完成了一半的工作。

于 2012-07-23T14:40:27.390 回答