HBase过滤器(filter)提供了强大得功能来帮助用户筛选需要的数据。
HBase中的get、scan都支持过滤器,,过滤器在服务端生效,这样可以保证被过滤掉的数据不会被传送到客户端,从而提高了代码运行的效率。
过滤器的执行流程:
过滤器可以根据列族、列、版本等更多的条件来对数据进行过滤,基于HBase 本身提供的三维有序(行键,列,版本有序),这些过滤器可以高效地完成查询过滤的任务,带有过滤器条件的RPC 查询请求会把过滤器分发到各个 RegionServer (这是一个服务端过滤器),这样也可以降低网络传输的压力。
介绍一下hbase过滤器中使用到的参数:
1、比较运算符 CompareFilter.CompareOp
参数 | 含义 |
LESS | 小于 |
LESS_OR_EQUAL | 小于等于 |
EQUAL | 等于 |
NOT_EQUAL | 不等于 |
GREATER_OR_EQUAL | 大于等于 |
GREATER | 大于 |
NO_OP | 排除所有符合条件的值 |
2、比较器
比较器作为过滤器的核心组成之一,用于处理具体的比较逻辑,例如字节级的比较,字符串级的比较等。
- RegexStringComparator :支持正则表达式的值比较。
- SubStringComparator :用于监测一个子串是否存在于值中,并且不区分大小写。
- BinaryPrefixComparator :前缀二进制比较器。与二进制比较器不同的是,只比较前缀是否相同。
- BinaryComparator :二进制比较器,用于按字典顺序比较 Byte 数据值。
比较运算符、比较器、过滤器的关系
过滤器的选择要看你想要过滤的数据类型,例如你想过滤rowkey、列簇、列值等类型的数据,那你就得选择不同的过滤器。比较器用于处理具体的比较逻辑,例如字节级的比较,字符串级的比较等,比如你想筛选rowkey,那你是想通过rowkey的前缀来查找、还是通过rowkey包含某个值、rowkey等于某个值 来筛选呢,这个时候就用到了比较器来定义。比较运算符用于判断比较器的内容到底是大于、小于或者等于的时候才是你想要的内容。比如我们想要查询某个人年龄为20的这个人的信息,那我们先找到我们要的过滤器,这里我们要通过列的值来找出所在行的信息,那我们选择SingleColumnValueFilter过滤器,然后查询的数据为某个确定的值(这里这个值为20),那我们选择BinaryComparator比较器。我们想要的是等于20的,所以比较运算符用EQUAL。
说明:
以下代码都是基于列值过滤器SingleColumnValueFilter进行使用的,SingleColumnValueFilter的作用为:
比较指定列的列值,用一列的值决定这一行的数据是否被过滤。在它的具体对象上,可以调用 setFilterIfMissing ( 或者 setFilterIfMissing ( false),默认的值是 false ,其作用是,对于要使用作为条件的列,如果这一列不存在,那么为 true ,这样
的行将会被过滤掉,如果为 false ,这样的行会包含在结果集中。
HBase过滤查询
本次使用的数据为员工信息,如下:
1、RegexStringComparator:支持正则表达式的值比较。(只粘贴部分代码)例子:职工表中在1980 年入职的员工编号
Scan scan=new Scan();
//设置过滤器"info:hiredata"以1980开头的的数据,RegexStringComparator匹配正则表达式
RegexStringComparator comp =new RegexStringComparator("1980.");
//ibfo簇中hiredata等于1980开头的
SingleColumnValueFilter filter = new SingleColumnValueFilter("info".getBytes(), "hiredata".getBytes(), CompareOp.EQUAL, comp);
scan.setFilter(filter);
2、SubStringComparator:用于监测一个子串是否存在于值中,并且不区分大小写。例子:查看职工姓名中包含S 的职工编号
Scan scan=new Scan();
SubstringComparator comp = new SubstringComparator("S");//包含S
//判断info簇,empname包含s的
SingleColumnValueFilter filter = new SingleColumnValueFilter("info".getBytes(), "empname".getBytes(), CompareOp.EQUAL, comp);
scan.setFilter(filter);
3、BinaryPrefixComparator:前缀二进制比较器。例子:查询上司编号以76 开头的员工编号和上司编号
Scan scan=new Scan();
//BinaryPrefixComparator匹配开头,前缀二进制比较器
BinaryPrefixComparator comp =new BinaryPrefixComparator("76".getBytes());//以76开头的
SingleColumnValueFilter filter = new SingleColumnValueFilter("info".getBytes(), "deptno".getBytes(), CompareOp.EQUAL, comp);
scan.setFilter(filter);
4、BinaryComparator:二进制比较器,用于按字典顺序比较 Byte 数据值。例子:查看姓名为JAMES 的职工编号和部门编号
JAMES 的职工编号和部门编号
Scan scan=new Scan();
BinaryComparator comp = new BinaryComparator("James".getBytes());
//奖金credit大于0的员工
SingleColumnValueFilter filter = new SingleColumnValueFilter("info".getBytes(), "credit".getBytes(), CompareOp.EQUAL, comp);
scan.setFilter(filter);
整体的代码为:
package Demo;
import java.io.IOException;
import java.util.Iterator;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.filter.BinaryComparator;
import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
import org.apache.hadoop.hbase.filter.SingleColumnValueFilter;
//import org.apache.hadoop.hbase.ipc.RpcServer.Connection;
public class SreenTest {
static final String tablename="emp";
public static void main(String[] args) throws IOException, InterruptedException{
Configuration conf = HBaseConfiguration.create();
conf.set("hbase.master", "master:16000");
conf.set("hbase.rootdir", "hdfs://master:8020/hbase");
conf.set("hbase.zookeeper.quorum", "slave1,slave2,slave3");
conf.set("hbase.zookeeper.property.clientPort", "2181");
Connection conn = ConnectionFactory.createConnection(conf);
scanData(conn);
}
public static void scanData(Connection conn) throws IOException{
//建立表连接
Table table=conn.getTable(TableName.valueOf(tablename));
// Scan scan=new Scan(ROWKEY2.getBytes());//查看rowkey为ROWKEY2的数据,如果查询全部则去掉ROWKEY2.getBytes()
Scan scan=new Scan();
//设置过滤器"info:hiredata"以1980开头的的数据,RegexStringComparator匹配正则表达式
// RegexStringComparator comp =new RegexStringComparator("1980.");
// SubstringComparator comp = new SubstringComparator("0");//包含S
//BinaryPrefixComparator匹配开头,前缀二进制比较器
// BinaryPrefixComparator comp =new BinaryPrefixComparator("1981".getBytes());//以76开头的
BinaryComparator comp = new BinaryComparator("0.00".getBytes());
SingleColumnValueFilter filter = new SingleColumnValueFilter("info".getBytes(), "credit".getBytes(), CompareOp.GREATER, comp);
scan.setFilter(filter);
ResultScanner scanner = table.getScanner(scan);
Iterator<Result> results = scanner.iterator();
while(results.hasNext()){
Result result=results.next();
System.out.println(new String(result.getRow()));//打印rowkey
for(Cell cell:result.rawCells()){
System.out.print(new String(CellUtil.cloneRow(cell))+'\t');
System.out.print(new String(CellUtil.cloneFamily(cell))+':');
System.out.print(new String(CellUtil.cloneQualifier(cell))+' ');
System.out.print(new String(CellUtil.cloneValue(cell)));
System.out.println();
}
}
}
}