zoukankan      html  css  js  c++  java
  • SpringBoot 使用hbaseclient操作HBase教程2(过滤器Filter)

    二、过滤器 Filter

    1,基本介绍

        Filter 可以在 Scan 的结果集基础之上,对返回的记录设置更多条件值,这些条件可以与 RowKey 有关,可以与列名有关,也可以与列值有关,还可以将多个 Filter 条件组合在一起等等。基于 Hbase 本身提供的三维有序(主键有序、列有序、版本有序),这些 Filter 可以高效的完成查询过滤的任务。

    注意:Filter 可能会导致查询响应时延变的不可控制。因为我们无法预测,为了找到一条符合条件的记录,背后需要扫描多少数据量,如果在有效限制了 Scan 范围区间(通过设置 StartRow 与 StopRow 限制)新版是(withstartRow和withstopRow)的前提下,该问题能够得到有效的控制。

    2,过滤操作的参数

    (1)要完成一个过滤的操作,至少需要两个参数。一个是如下抽象的操作符(比较运算符),Hbase 提供了枚举类型的变量来表示这些抽象的操作符:

    BinaryComparator 按字节索引顺序比较指定字节数组,采用 Bytes.compareTo(byte[])
    BinaryPrefixComparator 跟前面相同,只是比较左端的数据是否相同
    NullComparator 判断给定的是否为空
    BitComparator 按位比较
    RegexStringComparator 提供一个正则的比较器,仅支持 EQUAL 和非 EQUAL
    SubstringComparator 判断提供的子串是否出现在 value 中

    附:过滤器的分类以及样例演示

    1,准备工作

    (1)为了方便使用,首先对前文的 HBaseUtils.java 工具类稍作修改,增加如下方法,可以传入一个 Filter 继续数据过滤:

    /**
     * 获取数据(根据传入的filter)
     * @param tableName 表名
     * @param filter 过滤器
     * @return map
     */
    public List<Map<String, String>> getData(String tableName, Filter filter) {
        List<Map<String, String>> list = new ArrayList<>();
        try {
            Table table = hbaseAdmin.getConnection().getTable(TableName.valueOf(tableName));
            Scan scan = new Scan();
            // 添加过滤器
            scan.setFilter(filter);
            ResultScanner resultScanner = table.getScanner(scan);
            for(Result result : resultScanner) {
                HashMap<String, String> map = new HashMap<>();
                //rowkey
                String row = Bytes.toString(result.getRow());
                map.put("row", row);
                for (Cell cell : result.listCells()) {
                    //列族
                    String family = Bytes.toString(cell.getFamilyArray(),
                            cell.getFamilyOffset(), cell.getFamilyLength());
                    //
                    String qualifier = Bytes.toString(cell.getQualifierArray(),
                            cell.getQualifierOffset(), cell.getQualifierLength());
                    //
                    String data = Bytes.toString(cell.getValueArray(),
                            cell.getValueOffset(), cell.getValueLength());
                    map.put(family + ":" + qualifier, data);
                }
                list.add(map);
            }
            table.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return list;
    }

    在上一篇工具类里面已经封装好了

    (2)然后创建一张 test 表,并添加一些数据:

    2,行键过滤器(RowFilter)

    @RestController
    public class HelloController {
     
        @Autowired
        private HBaseUtils hbaseUtils;
     
        @GetMapping("/test")
        public void test() {
            // 筛选出行键大于row1的数据
            Filter rowFilter = new RowFilter(CompareOperator.GREATER,
                    new BinaryComparator("row1".getBytes()));
            List<Map<String, String>> tableData = hbaseUtils.getData("test", rowFilter);
            System.out.println(tableData);
        }
    }

     

    3,列簇过滤器(FamilyFilter)

    // 筛选出列族为cf2的数据
    Filter familyFilter = new FamilyFilter(CompareOperator.EQUAL,
            new BinaryComparator("cf2".getBytes()));
    List<Map<String, String>> tableData = hbaseUtils.getData("test", familyFilter);
    System.out.println(tableData);

     

    4,列过滤器(QualifierFilter)

    // 筛选出列名为b的数据
    Filter qualifierFilter = new QualifierFilter(CompareOperator.EQUAL,
            new BinaryComparator("b".getBytes()));
    List<Map<String, String>> tableData = hbaseUtils.getData("test", qualifierFilter);
    System.out.println(tableData);

     

    5,列前缀过滤器(ColumnPrefixFilter)

    //筛选出列前缀为b的数据
    ColumnPrefixFilter columnPrefixFilter = new ColumnPrefixFilter("b".getBytes());
    List<Map<String, String>> tableData = hbaseUtils.getData("test", columnPrefixFilter);
    System.out.println(tableData);

     

    6,值过滤器(ValueFilter)

    // 筛选出值为22的数据
    Filter valueFilter = new ValueFilter(CompareOperator.EQUAL.EQUAL,
            new SubstringComparator("22"));
    List<Map<String, String>> tableData = hbaseUtils.getData("test", valueFilter);
    System.out.println(tableData);

     

    7,单列值过滤器(SingleColumnValueFilter)

    //筛选出列族为cf2,列为c,且值为33的整行数据
    SingleColumnValueFilter singleColumnValueFilter = new SingleColumnValueFilter(
            "cf2".getBytes(),
            "c".getBytes(),
            CompareOperator.EQUAL.EQUAL,
            new SubstringComparator("33"));
    //如果不设置为 true,则那些不包含指定 column 的行也会返回
    singleColumnValueFilter.setFilterIfMissing(true);
    List<Map<String, String>> tableData = hbaseUtils.getData("test", singleColumnValueFilter);
    System.out.println(tableData);

     

    8,单列值排除器(SingleColumnValueExcludeFilter)

    SingleColumnValueExcludeFilter 跟上面的 SingleColumnValueFilter 功能一样,仅仅是不查询出该列的值。

    //筛选出列族为cf2,列为c,且值不为33的整行数据(但会把该列数据排除)
    SingleColumnValueExcludeFilter singleColumnValueExcludeFilter = new SingleColumnValueExcludeFilter(
            "cf2".getBytes(),
            "c".getBytes(),
            CompareOperator.EQUAL.EQUAL,
            new SubstringComparator("33"));
    //如果不设置为 true,则那些不包含指定 column 的行也会返回
    singleColumnValueExcludeFilter.setFilterIfMissing(true);
    List<Map<String, String>> tableData = hbaseUtils.getData("test", singleColumnValueExcludeFilter);
    System.out.println(tableData);

     

    9,行键前缀过滤器(PrefixFilter)

    //筛选出行键前缀为ro的整行数据
    PrefixFilter prefixFilter = new PrefixFilter("ro".getBytes());
    List<Map<String, String>> tableData = hbaseUtils.getData("test", prefixFilter);
    System.out.println(tableData);

     

    10,时间戳过滤器(TimestampsFilter)

    // 筛选出时间戳为1596248352266或1596248352285的数据
    List<Long> list = new ArrayList<>();
    list.add(1596248352266L);
    list.add(1596248352285L);
    TimestampsFilter timestampsFilter = new TimestampsFilter(list);
    List<Map<String, String>> tableData = hbaseUtils.getData("test", timestampsFilter);
    System.out.println(tableData);

     

     补充知识 查询最后10条

    scan 'mytable1', {COLUMNS => ['student:age', 'student:age'], REVERSED => true,LIMIT => 10, STARTROW => '0019000000',ENDROW => '0019000000'}

    代码如下

    //倒序且查询最近5个点
    Scan scan = new Scan();
    scan.withStopRow((vid+dateFormat.format(beforeThreemonth)).getBytes()).withStartRow((vid+dateFormat.format(now)).getBytes());
    scan.setLimit(5);
    scan.setReversed(true);

     

  • 相关阅读:
    Jenkins构建常见问题
    Jenkins搭建.NET自动编译发布远程环境
    Jenkins搭建.NET自动编译发布本地环境
    Web API系列(四) 使用ActionFilterAttribute 记录 WebApi Action 请求和返回结果记录
    C# 异步编程(async&await)
    [root@localhost ~]# /etc/httpd/conf/httpd.conf bash: /etc/httpd/conf/httpd.conf: 权限不够
    解决apache启动失败:Job for httpd.service failed.
    Windows环境下PHP配置详解
    如何以管理员身份运行cmd
    win8如何设置以管理员身份运行
  • 原文地址:https://www.cnblogs.com/shanheyongmu/p/15660690.html
Copyright © 2011-2022 走看看