HY,
Hbase允许列族在不同的行中具有不同的限定符。在我的情况下,列族具有以下规范
abc[cnt] # where cnt is an integer that can be any positive integer
我想要实现的是获取来自不同列族的所有数据,只有当所描述的限定符(在不同的列族中)的值匹配时才会获得。
缩小扫描范围我只需添加查询所需的两个系列。但这就是我现在所能得到的。
我已经使用SingleColumnValueFilter实现了相同的行为,但事后已知限定符。但对于这个,限定符可以是 abc1 , abc2 ......会有太多的选项,因此有太多的SingleColumnValueFilter。
然后我尝试使用ValueFilter,但此过滤器仅返回与值匹配的列,因此返回错误的列族。
您能想到实现目标的任何方法,查询列族中动态创建的限定符中的值并返回列族和其他列族的内容(如创建扫描时指定的那样)?最好只查询一次。
提前感谢任何输入。
更新:(有关评论中所述的说明)
以更加图形化的方式,行可能具有以下内容:
colfam1:aaa
colfam1:aab
colfam1:aac
colfam2:abc1
colfam2:abc2
然而,如果 colfam2的任何值具有例如,那么我想得到所有家族colfam1值x,关于colfam2:abc [cnt]是动态创建的事实,cnt是任何正整数
答案 0 :(得分:3)
我看到两种方法:客户端过滤或服务器端过滤。
客户端过滤更直接。扫描仅添加两个系列“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类。我相信您不能使用提供的过滤器类型来执行此操作。实现自己的Filter需要一些工作,您还需要将其编译为.jar并使其可供所有RegionServers使用。但是,它可以帮助您避免徒劳地发送大量“colfam1”数据。 向我展示如何自定义实现过滤器是太多的工作,因此我建议您阅读一本好书(例如HBase: The Definitive Guide)。但是,Filter代码看起来非常像我向您展示的客户端过滤,因此完成了一半的工作。