HBase过滤器( filter)提供了非常强大的特性来帮助用户提高其处理表中数据的效率。用户不仅可以使用 HBase中预定义好的过滤器,而且可以实现自定义的过滤器。下
HBase中两种主要的数据读取函数是get()和scan(),它们都支持直接访问数据和通过指定起止行键访问数据的功能。读者可以在查询中添加更多的限制条件来减少查询得到的数据量,这些限制可以是指定列族、列、时间戳以及版本号。
这些方法可以帮助用户控制哪些数据在查询时被包含其中,但是它们缺少一些细粒度的筛选功能,比如基于正则表达式对行键或值进行筛选。Get和scan两个类都支持过滤器,理由如下:这类对象提供的基本AP不能对行键、列名或列值进行过滤,但是通过过滤器可以达到这个目的。过滤器最基本的接口叫 Filter,除此之外,还有一些由 HBase提供的无需编程就可以直接使用的类。
同时用户还可以通过继承 Filter类来实现自己的需求。所有的过滤器都在服务端生效,叫做谓词下推( predicate push down)。这样可以保证被过滤掉的数据不会被传送到客户端。用户可以在客户端代码中实现过滤的功能(但会影响系统性能),因为在这种情况下服务器端需要传输更多的数据到客户端,用户应当尽量避免这种情况。
1、FilterList
FilterList 代表一个过滤器列表,可以添加多个过滤器进行查询,多个过滤器之间的关系有:
- 与关系(符合所有):FilterList.Operator.MUST_PASS_ALL
- 或关系(符合任一):FilterList.Operator.MUST_PASS_ONE
使用方法:
FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ONE);
Scan s1 = new Scan();
filterList.addFilter(new SingleColumnValueFilter(Bytes.toBytes(“f1”),Bytes.toBytes(“c1”),CompareOp.EQUAL,Bytes.toBytes(“v1”)));
filterList.addFilter(new SingleColumnValueFilter(Bytes.toBytes(“f1”),Bytes.toBytes(“c2”),CompareOp.EQUAL,Bytes.toBytes(“v2”)));
// 添加下面这一行后,则只返回指定的cell,同一行中的其他cell不返回
s1.addColumn(Bytes.toBytes(“f1”), Bytes.toBytes(“c1”));
s1.setFilter(filterList); //设置filter
ResultScanner ResultScannerFilterList = table.getScanner(s1); //返回结果列表
2、过滤器的种类
过滤器的种类:
列值过滤器—SingleColumnValueFilter
过滤列植的相等、不等、范围等
列名前缀过滤器—ColumnPrefixFilter
过滤指定前缀的列名
多个列名前缀过滤器—MultipleColumnPrefixFilter
过滤多个指定前缀的列名
rowKey过滤器—RowFilter
通过正则,过滤rowKey值。
3、列值过滤器-SingleColumnValueFilter
SingleColumnValueFilter 列值判断
- 相等 (CompareOp.EQUAL ),
- 不等(CompareOp.NOT_EQUAL),
- 范围 (e.g., CompareOp.GREATER)…………
下面示例检查列值和字符串'values' 相等...
SingleColumnValueFilter f = new SingleColumnValueFilter(Bytes.toBytes("cFamily"),Bytes.toBytes("column"),CompareFilter.CompareOp.EQUAL, Bytes.toBytes("values"));
s1.setFilter(f);
注意:如果过滤器过滤的列在数据表中有的行中不存在,那么这个过滤器对此行无法过滤。
4、列名前缀过滤器-ColumnPrefixFilter
过滤器—ColumnPrefixFilter
ColumnPrefixFilter 用于指定列名前缀值相等
ColumnPrefixFilter f = new ColumnPrefixFilter(Bytes.toBytes("values"));
s1.setFilter(f);
5、多个列值前缀过滤器-MultipleColumnPrefixFilter
MultipleColumnPrefixFilter 和 ColumnPrefixFilter 行为差不多,但可以指定多个前缀
byte[][] prefixes = new byte[][] {Bytes.toBytes("value1"),Bytes.toBytes("value2")};
Filter f = new MultipleColumnPrefixFilter(prefixes);
s1.setFilter(f);
6、rowKey过滤器-RowFilter
RowFilter 是rowkey过滤器
通常根据rowkey来指定范围时,使用scan扫描器的StartRow和StopRow方法比较好。
Filter f = new RowFilter(CompareFilter.CompareOp.EQUAL, new RegexStringComparator("^1234")); //匹配以1234开头的rowkey
s1.setFilter(f);