SpringBoot - 使用hbase-client操作HBase教程2(过滤器Filter)
作者:hangge | 2020-09-11 08:10
二、过滤器 Filter
1,基本介绍
Filter 可以在 Scan 的结果集基础之上,对返回的记录设置更多条件值,这些条件可以与 RowKey 有关,可以与列名有关,也可以与列值有关,还可以将多个 Filter 条件组合在一起等等。基于 Hbase 本身提供的三维有序(主键有序、列有序、版本有序),这些 Filter 可以高效的完成查询过滤的任务。
注意:Filter 可能会导致查询响应时延变的不可控制。因为我们无法预测,为了找到一条符合条件的记录,背后需要扫描多少数据量,如果在有效限制了 Scan 范围区间(通过设置 StartRow 与 StopRow 限制)的前提下,该问题能够得到有效的控制。
2,过滤操作的参数
(1)要完成一个过滤的操作,至少需要两个参数。一个是如下抽象的操作符(比较运算符),Hbase 提供了枚举类型的变量来表示这些抽象的操作符:- LESS:小于(即 <)
- LESS_OR_EQUAL:小于等于(即 <=)
- EQUAL:等于(即 =)
- NOT_EQUAL:不等于(即 <>)
- GREATER_OR_EQUAL:大于等于(即 >=)
- GREATER(即 >)
- NO_OP:排除所有
(2)另外一个就是具体的比较器(Comparator),代表具体的比较逻辑,如果可以提高字节级的比较、字符串级的比较等:
- 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);
全部评论(0)