SpringBoot - 使用hbase-client操作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);

 

 

 

posted @ 2021-12-08 11:37  山河永慕~  阅读(624)  评论(0编辑  收藏  举报