(六)hbase的过滤器使用

hbase的过滤器使用

1:过滤器

在这里插入图片描述

Hbase 提供了种类丰富的过滤器(filter)来提高数据处理的效率,用户可以通过内置或自定义的过滤器来对数据进行过滤,所有的过滤器都在服务端生效,即谓词下推(predicate push down)。这样可以保证过滤掉的数据不会被传送到客户端,从而减轻网络传输和客户端处理的压力。
命令端操作“scan”和“get”可以执行过滤器。

1:Filter接口和FilterBase抽象类

Filter 接口中定义了过滤器的基本方法,FilterBase 抽象类实现了 Filter 接口。所有内置的过滤器则直接或者间接继承自 FilterBase 抽象类。用户只需要将定义好的过滤器通过 setFilter 方法传递给 Scan 或 put 的实例即可。

2: 过滤器分类

HBase 内置过滤器可以分为三类:分别是比较过滤器,专用过滤器和包装过滤器。

2.1:比较过滤器CompareFilter

在这里插入图片描述

RowFilter :基于行键来过滤数据;
FamilyFilterr :基于列族来过滤数据;
QualifierFilterr :基于列限定符(列名)来过滤数据;
ValueFilterr :基于单元格 (cell) 的值来过滤数据;
	scan 'testByCrq', FILTER=>"ValueFilter(=,'substring:111')"//不指定列时全部列的值,也可以指定单独列进行过滤
DependentColumnFilter :指定一个参考列来过滤其他列的过滤器,过滤的原则是基于参考列的时间戳来进行筛选 。

比较器

步骤3中的'binary:中国',这都是比较器。HBase的filter有四种比较器: 
(1)二进制比较器:如’binary:abc’,按字典排序跟’abc’进行比较 
(2)二进制前缀比较器:如’binaryprefix:abc’,按字典顺序只跟’abc’比较前3个字符 
(3)正则表达式比较器:如’regexstring:ab*yz’,按正则表达式匹配以ab开头,以yz结尾的值。这个比较器只能使用=!=两个比较运算符。 
(4)子串比较器:如’substring:abc123’,匹配以abc123开头的值。这个比较器只能使用=!=两个比较运算符。

比较运算符

1. LESS (<)                小于
2. LESS_OR_EQUAL (<=)    小于等于
3. EQUAL (=)                    等于
4. NOT_EQUAL (!=)              不等于
5. GREATER_OR_EQUAL (>=)            大于等于
6. GREATER (>)               大于

2.2:专用过滤器

单列列值过滤器 (SingleColumnValueFilter):基于某列(参考列)的值决定某行数据是否被过滤
单列列值排除器 (SingleColumnValueExcludeFilter)
行键前缀过滤器 (PrefixFilter):基于 RowKey 值决定某行数据是否被过滤。
列名前缀过滤器 (ColumnPrefixFilter):基于列限定符(列名)决定某行数据是否被过滤
分页过滤器 (PageFilter)
时间戳过滤器 (TimestampsFilter)
首次行键过滤器 (FirstKeyOnlyFilter):只扫描每行的第一列,扫描完第一列后就结束对当前行的扫描,并跳转到下一行。
相比于全表扫描,其性能更好,通常用于行数统计的场景,因为如果某一行存在,则行中必然至少有一列

2.3:包装过滤器

SkipFilter过滤器:包装一个过滤器,当被包装的过滤器遇到一个需要过滤的 KeyValue 实例时,则拓展过滤整行数据。下面是一个使用示例:
WhileMatchFilter过滤器: 包装一个过滤器,当被包装的过滤器遇到一个需要过滤的 KeyValue 实例时,则结束本次扫描,返回已经扫描到的结果。也就是只返回一条符合数据
FilterList过滤器:需要多个过滤器共同作用于一次查询的时候,就需要使用 FilterList。FilterList 支持通过构造器或者 addFilter 方法传入多个过滤器。

3:shell使用过滤器操作示例

过滤器使用格式:FILTER => “(filterName(运算符,‘比较器’))”

3.1:比较器和运算符:

比较运算符

1. LESS (<)                小于
2. LESS_OR_EQUAL (<=)    小于等于
3. EQUAL (=)                    等于
4. NOT_EQUAL (!=)              不等于
5. GREATER_OR_EQUAL (>=)            大于等于
6. GREATER (>)               大于

比较器:

binary等于比较器,用于值等于
binaryprefix:abc:前缀模糊匹配比较器
substring:abc123:值比较器,包含该值
  • 1:ValueFilterr 值过滤器:查询表中任一列值为中国的数据
    scan’person’, {FILTER => “ValueFilter(=, ‘binary:中国’)”}

  • 2:RowFilter:rowkey过滤器
    过滤方式是通过rowkey过滤,匹配出rowkey含111的数据
    scan ‘testByCrq’, FILTER=>“RowFilter(=,‘substring:111’)”

  • 3:SingleColumnValueFilter列值过滤器
    匹配符合该列的数据
    scan ‘tableName’, {FILTER => “(SingleColumnValueFilter(‘info列簇’,‘event_time列名’,=,‘binary:2021-12-16 09:10:06’))”}

ValueFilterr 值过滤器:过滤rk0001行数据值等于中国的。
get 'person', 'rk0001', {FILTER => "ValueFilter(=, 'binary:中国')"}  
scan 'person', {COLUMNS => ['info', 'data'], FILTER => "(QualifierFilter(=,'substring:a'))"}

4:java开发过滤器示例

1:单过滤器

 // 声明静态配置
    static Configuration conf = null;
    private static final String ZK_CONNECT_STR = "ip:2181";

    static {
        conf = HBaseConfiguration.create();
        conf.set("hbase.zookeeper.quorum", ZK_CONNECT_STR);
    }

    public static void main(String[] args) throws IOException {
        HTable table = new HTable(conf, "person".getBytes());
        Scan scan = new Scan(Bytes.toBytes("person_zhang_000001"), Bytes.toBytes("person_zhang_000002"));

        //前缀过滤器----针对行键
        Filter filter = new PrefixFilter(Bytes.toBytes("person"));

        //行过滤器  ---针对行键
        ByteArrayComparable rowComparator = new BinaryComparator(Bytes.toBytes("person_zhang_000001"));
        RowFilter rf = new RowFilter(CompareFilter.CompareOp.LESS_OR_EQUAL, rowComparator);

        rf = new RowFilter(CompareFilter.CompareOp.EQUAL , new SubstringComparator("_2016-12-31_"));

        //单值过滤器1完整匹配字节数组
        new SingleColumnValueFilter("base_info".getBytes(), "name".getBytes(), CompareFilter.CompareOp.EQUAL, "zhangsan".getBytes());

        //单值过滤器2 匹配正则表达式
        ByteArrayComparable comparator = new RegexStringComparator("zhang.");
        new SingleColumnValueFilter("info".getBytes(), "NAME".getBytes(), CompareFilter.CompareOp.EQUAL, comparator);

        //单值过滤器3匹配是否包含子串,大小写不敏感
        comparator = new SubstringComparator("wu");
        new SingleColumnValueFilter("info".getBytes(), "NAME".getBytes(), CompareFilter.CompareOp.EQUAL, comparator);

        //键值对元数据过滤-----family过滤----字节数组完整匹配
        FamilyFilter ff = new FamilyFilter(CompareFilter.CompareOp.EQUAL ,
                new BinaryComparator(Bytes.toBytes("base_info"))   //表中不存在inf列簇,过滤结果为空
        );

        //键值对元数据过滤-----family过滤----字节数组前缀匹配
        ff = new FamilyFilter(
                CompareFilter.CompareOp.EQUAL ,
                new BinaryPrefixComparator(Bytes.toBytes("inf"))   //表中存在以inf打头的列簇info,过滤结果为该列簇所有行
        );

        //键值对元数据过滤-----qualifier过滤----字节数组完整匹配
        filter = new QualifierFilter(
                CompareFilter.CompareOp.EQUAL ,
                new BinaryComparator(Bytes.toBytes("na"))   //表中不存在na列,过滤结果为空
        );
        filter = new QualifierFilter(
                CompareFilter.CompareOp.EQUAL ,
                new BinaryPrefixComparator(Bytes.toBytes("na"))   //表中存在以na打头的列name,过滤结果为所有行的该列数据
        );

        //基于列名(即Qualifier)前缀过滤数据的ColumnPrefixFilter
        filter = new ColumnPrefixFilter("na".getBytes());

        //基于列名(即Qualifier)多个前缀过滤数据的MultipleColumnPrefixFilter
        byte[][] prefixes = new byte[][] {Bytes.toBytes("na"), Bytes.toBytes("me")};
        filter = new MultipleColumnPrefixFilter(prefixes);

        //为查询设置过滤条件
        scan.setFilter(filter);

        scan.addFamily(Bytes.toBytes("base_info"));
        //一行
//		Result result = table.get(get);
        //多行的数据
        ResultScanner scanner = table.getScanner(scan);
        table.close();
    }

结果集处理:ResultScanner

        for(Result r : scanner){
            /**
             for(KeyValue kv : r.list()){
             String family = new String(kv.getFamily());
             System.out.println(family);
             String qualifier = new String(kv.getQualifier());
             System.out.println(qualifier);
             System.out.println(new String(kv.getValue()));
             }
             */
            //直接从result中取到某个特定的value
            byte[] value = r.getValue(Bytes.toBytes("base_info"), Bytes.toBytes("name"));
            System.out.println(new String(value));
        }

2:多个过滤器

通过FilterList添加多个过滤器可以进行使用

FilterList filterList = new FilterList();
filterList.addFilter(singleColumnValueFilter);
filterList.addFilter(pageFilter);

scan.setFilter(filterList);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值