Hbase提供了种类丰富的过滤器(filter)来提高数据处理的效率,用户可以通过内置或自定义的过滤器来对数据进行过滤,所有的过滤器都在服务端生效,即谓词下推(predicate push down)。这样可以保证过滤掉的数据不会被传送到客户端,从而减轻网络传输和客户端处理的压力。
Filter接口中定义了过滤器的基本方法,FilterBase抽象类实现了Filter接口。所有内置的过滤器则直接或者间接继承自FilterBase抽象类。用户只需要将定义好的过滤器通过setFilter方法传递给Scan或put的实例即可。
// Scan 中定义的setFilter
@Override
public Scan setFilter(Filter filter) {
super.setFilter(filter);
return this;
}
1
2
3
4
5
6
// Get 中定义的setFilter
@Override
public Get setFilter(Filter filter) {
super.setFilter(filter);
return this;
}
所有比较过滤器均继承自CompareFilter。创建一个比较过滤器需要两个参数,分别是比较运算符和比较器实例。
public CompareFilter(final CompareOp compareOp,final ByteArrayComparable comparator) {
this.compareOp = compareOp;
this.comparator = comparator;
}
3.1 比较运算符
LESS (<)
LESS_OR_EQUAL (<=)
EQUAL (=)
NOT_EQUAL (!=)
GREATER_OR_EQUAL (>=)
GREATER (>)
NO_OP (排除所有符合条件的值)
比较运算符均定义在枚举类CompareOperator中
@InterfaceAudience.Public
public enum CompareOperator {
LESS,
LESS_OR_EQUAL,
EQUAL,
NOT_EQUAL,
GREATER_OR_EQUAL,
GREATER,
NO_OP,
}
注意:在 1.x 版本的HBase中,比较运算符定义在CompareFilter.CompareOp枚举类中,但在2.0之后这个类就被标识为 @deprecated ,并会在3.0移除。所以2.0之后版本的HBase需要使用 CompareOperator这个枚举类。
所有比较器均继承自ByteArrayComparable抽象类,常用的有以下几种:
BinaryPrefixComparator 和 BinaryComparator的区别不是很好理解,这里举例说明一下:
在进行EQUAL的比较时,如果比较器传入的是abcd的字节数组,但是待比较数据是abcdefgh:
如果使用的是BinaryPrefixComparator比较器,则比较以abcd字节数组的长度为准,即efgh不会参与比较,这时候认为abcd与abcdefgh 是满足EQUAL条件的;
如果使用的是BinaryComparator比较器,则认为其是不相等的。
RowFilter :基于行键来过滤数据;
FamilyFilterr :基于列族来过滤数据;
QualifierFilterr :基于列限定符(列名)来过滤数据;
ValueFilterr :基于单元格(cell) 的值来过滤数据;
DependentColumnFilter :指定一个参考列来过滤其他列的过滤器,过滤的原则是基于参考列的时间戳来进行筛选 。
前四种过滤器的使用方法相同,均只要传递比较运算符和运算器实例即可构建,然后通过setFilter方法传递给scan:
Filter filter = new RowFilter(CompareOperator.LESS_OR_EQUAL,
new BinaryComparator(Bytes.toBytes("xxx")));
scan.setFilter(filter);
/**
* @Auther: 多易教育-行哥
* @Date: 2020/6/15
* @Description:
* 列族过滤器
*/
public class ColumnFamilyFilterDemo {
public static void main(String[] args) throws Exception {
Table tb = HbaseUtils.getHbaseTable("tb_filter");
Scan scan = new Scan();
// 设置列族过滤器 列族
FamilyFilter ff = new FamilyFilter(CompareOperator.EQUAL, new SubstringComparator("cf1"));
//行
RowFilter rowFilter = new RowFilter(CompareOperator.GREATER, new BinaryComparator("k0001".getBytes()));
// 属性
QualifierFilter qualifierFilter = new QualifierFilter(CompareOperator.EQUAL, new BinaryComparator("id".getBytes()));
FilterList where = new FilterList(ff, rowFilter, qualifierFilter);
// 查询列族cf1 的id属性 > k0001
scan.setFilter(where);
ResultScanner scanner = tb.getScanner(scan);
// 遍历数据
Iterator iterator = scanner.iterator();
while(iterator.hasNext()){
Result result = iterator.next();
HbaseUtils.showData(result);
}
tb.close();
}
}
/**
* @Auther: 多易教育-行哥
* @Date: 2020/6/15
* @Description:
* 行过滤 RowFilter
* 多条件过滤 new FilterList(filter1, filter2);
*/
public class RowFIlterDemo {
public static void main(String[] args) throws Exception {
Table tb = HbaseUtils.getHbaseTable("tb_filter");
Scan scan = new Scan();
/**
* 参数一 比较运算符
* LESS,小于
* LESS_OR_EQUAL, 小于等于
* EQUAL,
* NOT_EQUAL,
* GREATER_OR_EQUAL,
* GREATER,
* NO_OP,
* 参数二 比较规则
*/
// >= 第二行
RowFilter filter1 = new RowFilter(CompareOperator.GREATER_OR_EQUAL, new BinaryComparator("k0002".getBytes()));
// <= 第四行
RowFilter filter2 = new RowFilter(CompareOperator.LESS_OR_EQUAL, new BinaryComparator("k0003".getBytes()));
// 设置行过滤器
/* scan.setFilter(filter1);
scan.setFilter(filter2);*/
// 设置多条件过滤 类似于 SQL中的where id >=2 and id <=10
//FilterList 参数是可变的 可以传入多个过滤器 同时生效
FilterList filterList = new FilterList(filter1, filter2);
scan.setFilter(filterList) ;
ResultScanner scanner = tb.getScanner(scan);
// 遍历数据
Iterator iterator = scanner.iterator();
while(iterator.hasNext()){
Result result = iterator.next();
HbaseUtils.showData(result);
}
tb.close();
}
}
/**
* @Auther: 多易教育-行哥
* @Date: 2020/6/15
* @Description: 属性过滤器
*/
public class QualifierFilterDemo {
public static void main(String[] args) throws Exception {
Table tb = HbaseUtils.getHbaseTable("tb_filter");
Scan scan = new Scan();
// 设置属性过滤器
QualifierFilter qf = new QualifierFilter(CompareOperator.EQUAL, new BinaryComparator("id".getBytes()));
scan.setFilter(qf);
ResultScanner scanner = tb.getScanner(scan);
// 遍历数据`
Iterator iterator = scanner.iterator();
while(iterator.hasNext()){
Result result = iterator.next();
HbaseUtils.showData(result);
}
tb.close();
}
}
**
* @Auther: 多易教育-行哥
* @Date: 2020/6/15
* @Description: 值
*/
public class Demo1 {
public static void main(String[] args) throws Exception {
// 查询数据 根据条件筛选数据
Table tb = HbaseUtils.getHbaseTable("tb_spl2");
/*Get get = new Get("rk001".getBytes());
get.addColumn("cf".getBytes(),"name".getBytes()) ;
Result result = tb.get(get);
HbaseUtils.showData(result);*/
Scan scan = new Scan();
//K: tb_name:rk001:cf:属性 V: 值
/**
* 参数一 比较运算符 条件比较运算符 where age
* 参数二 ByteArrayComparable 怎么比较 比较的标准 字符串 正则 字节
*/
ValueFilter ls = new ValueFilter(CompareOperator.EQUAL, new SubstringComparator("LS"));
// 设置过滤器
scan.setFilter(ls) ;
ResultScanner scanner = tb.getScanner(scan);
Iterator iterator = scanner.iterator();
while(iterator.hasNext()){
Result next = iterator.next();
HbaseUtils.showData(next);
}
tb.close();
}
}
以上都是讲解单个过滤器的作用,当需要多个过滤器共同作用于一次查询的时候,就需要使用FilterList。FilterList支持通过构造器或者addFilter方法传入多个过滤器。
// 构造器传入
public FilterList(final Operator operator, final List filters)
public FilterList(final List filters)
public FilterList(final Filter... filters)
// 方法传入
public void addFilter(List filters)
public void addFilter(Filter filter)
多个过滤器组合的结果由operator参数定义 ,其可选参数定义在Operator枚举类中。只有MUST_PASS_ALL和MUST_PASS_ONE两个可选的值:
MUST_PASS_ALL :相当于AND,必须所有的过滤器都通过才认为通过;
MUST_PASS_ONE :相当于OR,只有要一个过滤器通过则认为通过。
@InterfaceAudience.Public
public enum Operator {
/** !AND */
MUST_PASS_ALL,
/** !OR */
MUST_PASS_ONE
}
看代码
**
* @Auther: 多易教育-行哥
* @Date: 2020/6/15
* @Description: id 为 1004的数据
*/
public class Demo2 {
public static void main(String[] args) throws Exception {
// 查询数据 根据条件筛选数据
Table tb = HbaseUtils.getHbaseTable("tb_filter");
Scan scan = new Scan();
// 值
ValueFilter value = new ValueFilter(CompareOperator.EQUAL, new BinaryComparator("1004".getBytes()));
//属性
QualifierFilter qualifierFilter = new QualifierFilter(CompareOperator.EQUAL, new BinaryComparator("id".getBytes()));
// and 操作 or id = 1004 name = zss
FilterList list = new FilterList(value , qualifierFilter);
// 设置过滤器
scan.setFilter(list) ;
ResultScanner scanner = tb.getScanner(scan);
Iterator iterator = scanner.iterator();
while(iterator.hasNext()){
Result next = iterator.next();
HbaseUtils.showData(next);
}
tb.close();
}
}