HBase过滤器(filter)提供了强大得功能来帮助用户筛选需要的数据。

HBase中的get、scan都支持过滤器,,过滤器在服务端生效,这样可以保证被过滤掉的数据不会被传送到客户端,从而提高了代码运行的效率。

过滤器的执行流程:

hbase shell 过滤删除 hbase shell valuefilter_hadoop

过滤器可以根据列族、列、版本等更多的条件来对数据进行过滤,基于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过滤查询

本次使用的数据为员工信息,如下:

hbase shell 过滤删除 hbase shell valuefilter_hadoop_02

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();
			}
		}
	}	
}