Hbase Javaapi Filter和scan相关问题

摸索了几天Hbase关于利用Filter去做scan,也是很有体会。

先简单介绍一下我的表结构,然后描述我的需求,最后给出利用Filter去查询的方案。

rowkey:Filename+index1+index2  例子:xxx_4_9 (其中xxx为filename,4为index1,9为index2),列簇设计为:Info和Data两组,其中Info就包含一些常规信息,Data中的列是按照ID构造,即1,2,3......,即为:Data:1,Data:2...

1、根据rowkey前缀查询数据

根据filename和index1进行查询,其中index1是一个区间,函数接口如下:

getFileData(String Filename, int from, int to)

通常Filter可以传入两个参数,第一个参数是比较运算符CompareOp,第二个参数是比较器ByteArrayComparable。

其中比较运算符有如下:

EQUAL                                 相等
GREATER                            大于
GREATER_OR_EQUAL      大于等于
LESS                                    小于
LESS_OR_EQUAL              小于等于
NOT_EQUAL                       不等于
比较器有如下:

BinaryComparator              匹配完整字节数组 
BinaryPrefixComparator     匹配字节数组前缀 
BitComparator                    Performs a bitwise comparison, providing a BitwiseOp class with OR, and XOR operators.
NullComparator                  Does not compare against an actual value but whether a given one is null, or not  null.
RegexStringComparator    正则表达式匹配
SubstringComparator         子串匹配

关于这里的任务,可以用PrefixFilter去做,但是这个PrefixFilter不能传入比较运算符和比较器,只能传入前缀字符串。

当然可以用FilterList,其中FilterList可以设置 MUST_PASS_ONE或MUST_PASS_ALL条件,这里也尝试了利用FilterList,结合其他的RowFilter去做,如果利用BinaryPrefixComparator,会出现的问题就是说,想匹配xxx_4_all,那么有可能会匹配出xxx_40_,xxx_41_....,如果用RegexStringComparator去匹配,只能用EQUAL,而不能用GREATER_OR_EQUAL等条件,这里给出一种方案是,利用PrefixFilter,结合FillterList,将from和to生成一个list,然后对每个list设置一个PrefixFilter,然后加入到FilterList中,具体代码如下:

        Scan scan = new Scan();
        int FROM = from;
        ArrayList<String> range = new ArrayList<>();
        while (FROM <= to) {
            range.add(String.valueOf(FROM));
            FROM++;
        }
        FilterList list = new FilterList(FilterList.Operator.MUST_PASS_ONE);
        for (String s : range) {
            PrefixFilter filter = new PrefixFilter(Bytes.toBytes(Filename + "_" + s + "_"));
            list.addFilter(filter);
        }
        scan.setFilter(list);
        //使用HTable得到resultcanner实现类的对象
        ResultScanner resultScanner = table.getScanner(scan);

2、根据Rowkey并指定列名

具体要求就是在前一个任务的基础之上,不是过滤出所有的数据,而是指定相关列名,具体函数接口如下:

getFileData(String Filename, int from, int to, String... columns)

给出方案如下:

一个FilterList用于过滤Rowkey,一个FilterList用于过滤列名,这两个FilterList,均采用MUST_PASS_ONE条件,然后将这两个FilterList,加入一个总的FilterList中,条件采用MUST_PASS_ALL,具体代码如下:

        //得到用于扫描region的对象
        Scan scan = new Scan();
        int FROM = from;
        ArrayList<String> range = new ArrayList<>();
        while (FROM <= to) {
            range.add(String.valueOf(FROM));
            FROM++;
        }
        FilterList list_all = new FilterList(FilterList.Operator.MUST_PASS_ALL);

        FilterList list_col = new FilterList(FilterList.Operator.MUST_PASS_ONE);
        for (String column : columns) {
            Filter filter_col = new QualifierFilter(CompareFilter.CompareOp.EQUAL, new BinaryComparator(Bytes.toBytes(column)));
            list_col.addFilter(filter_col);
        }
        FilterList list = new FilterList(FilterList.Operator.MUST_PASS_ONE);
        for (String s : range) {
            PrefixFilter filter = new PrefixFilter(Bytes.toBytes(Filename + "_" + s + "_"));
            list.addFilter(filter);
        }
        list_all.addFilter(list_col);
        list_all.addFilter(list);
        scan.setFilter(list_all);
        //使用HTable得到resultcanner实现类的对象
        ResultScanner resultScanner = table.getScanner(scan);

 

总结起来,如果要利用scan和filter结合进行数据查询,那么需要去了解有哪些Filter,然后构造自己的Filter,这里给出一个Filter写的比较全的博客:Filter

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值