一、介绍
除了上述介绍的比较过滤器以外,hbase还提供了许多专门用于一些特殊场景的过滤器,这样的过滤器叫做专用过滤器
二、例子
1、单列值过滤器:SingleColumnValueFilter
该过滤器用在用用户指定的某一类来过滤一行,即如果某一行的指定列的最大版本的数据不符合条过滤器条件时,整行数据将要被过滤掉。
该过滤器有两个构造函数:
(1)SingleColumnValueFilter(byte[] family,byte[] column,CompareOp compareOp,byte[] value)
(2)SingleColumnValueFilter(byte[] family,byte[] column,CompareOp compareOp,ByteArrayComparable valuessss)
public void example(String tableName)
{
Configuration conf=init();
try {
conf=init();
HTable table=new HTable(conf, tableName);
//创建单行值过滤器
SingleColumnValueFilter filter=new SingleColumnValueFilter(Bytes.toBytes("test"),Bytes.toBytes("test1"),CompareOp.EQUAL,Bytes.toBytes("value5"));
//也可以使用其他比较器
SingleColumnValueFilter filter2=new SingleColumnValueFilter(Bytes.toBytes("test"),Bytes.toBytes("test1"),CompareOp.EQUAL, new SubstringComparator("value"));
//创建scan
Scan scan=new Scan();
filter.setFilterIfMissing(true);
scan.setFilter(filter2);
//获取结果并尽心显示
ResultScanner rs=table.getScanner(scan);
Result result=null;
while((result=rs.next())!=null)
{
KeyValue[] kvs=result.raw();
for(KeyValue kv:kvs)
{
System.out.println(kv.toString());
System.out.println(kv.getValue().toString());
}
}
//释放资源
rs.close();
table.close();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
2、单列值排除过滤器:SingleColumnValueExcludeFilter
该过滤器功能与上述的过滤器基本上是相同的,唯一的不同点就在于,该过滤器会将参考列进行过滤,即返回的数据中不含有参考列的数据。
public void example(String tableName)
{
Configuration conf=init();
try {
conf=init();
HTable table=new HTable(conf, tableName);
//创建单行值过滤器
SingleColumnValueExcludeFilter filter=new SingleColumnValueExcludeFilter(Bytes.toBytes("test"),Bytes.toBytes("test1"),CompareOp.EQUAL,Bytes.toBytes("value5"));
//也可以使用其他比较器
SingleColumnValueExcludeFilter filter2=new SingleColumnValueExcludeFilter(Bytes.toBytes("test"),Bytes.toBytes("test1"),CompareOp.EQUAL, new SubstringComparator("value"));
//创建scan
Scan scan=new Scan();
scan.setFilter(filter2);
//获取结果并尽心显示
ResultScanner rs=table.getScanner(scan);
Result result=null;
while((result=rs.next())!=null)
{
KeyValue[] kvs=result.raw();
for(KeyValue kv:kvs)
{
System.out.println(kv.toString());
System.out.println(kv.getValue().toString());
}
}
//释放资源
rs.close();
table.close();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
3、前缀过滤器:PrefixFilter(byte[] prefix)
对rowKey的前缀进行筛选,前缀不符合过滤器条件的行被过滤掉
该过滤器在构造时直接指定前缀条件为:
public void example(String tableName)
{
Configuration conf=init();
try {
HTable table=new HTable(conf, tableName);
//创建前缀过滤器
PrefixFilter filter=new PrefixFilter(Bytes.toBytes("row"));
Scan scan=new Scan();
scan.setFilter(filter);
//获取结果数据
ResultScanner rs=table.getScanner(scan);
//进行数据显示
Result result=null;
while((result=rs.next())!=null)
{
KeyValue[] kvs=result.raw();
for(KeyValue kv:kvs)
{
System.out.println(kv.toString());
System.out.println(Bytes.toString(kv.getValue()));
}
}
//释放资源
rs.close();
table.close();
} catch (Exception e) {
// TODO: handle exception
}
}
4、分页过滤器:PageFilter(int n)
分页过滤器,每次只返回从开始的row,个数为n(构造函数中的 n)的连续行的数据。
需要注意的是:分页过滤器只能返回一次数据,因此如果需要将下一页的数据返回时,需要重新发送请求,并且需要设置好相应的startRow的值,如果没有设置startRow的话,其永远只返回前 n 个数据。
public void example(String tableName)
{
Configuration conf=init();
try {
HTable table=new HTable(conf, tableName);
//准备循环表 结果
byte[] endRow=null;
while(true)
{
//创建scan对象
Scan scan=new Scan();
//判断endrow是否为null
if(endRow!=null)
{
byte[] startRow=Bytes.add(endRow,Bytes.toBytes("row-1"));
scan.setStartRow(startRow);
}
//生成过滤器
PageFilter filter=new PageFilter((long)3);
scan.setFilter(filter);
//获取数据并显示
ResultScanner rs=table.getScanner(scan);
Result result=null;
int localCount=0;
while((result=rs.next())!=null)
{
localCount++;
KeyValue[] kvs=result.raw();
for(KeyValue kv:kvs)
{
System.out.println(kv.toString());
System.out.println(Bytes.toString(kv.getValue()));
}
//设置最后的进制
endRow=result.getRow();
}
//释放资源
rs.close();
//判断循环是否完成
if(localCount==0)
{
table.close();
break;
}
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
5、行健过滤器:KeyOnlyFilter
行健和行值需要进行区分:
行值(row):在一行数据中,其row值的是一行中的唯一标示。
行键(Key):在HBase底层存储中,数据都是以KeyValue对象的形式存在,而在KeyValue对象中,Key包含了一个单元格的row、family、qualifier、ts、type 几个重要的信息,而Value中只有单元格真是的数据。也就是说Key是包含row的。
该过滤器在进行数据过滤器值返回Key,而不返回Value值。
public void example(String tableName)
{
Configuration conf=init();
try {
HTable table=new HTable(conf, tableName);
//创建过滤器
KeyOnlyFilter filter=new KeyOnlyFilter();
Scan scan=new Scan();
scan.setFilter(filter);
//进行数据查询返回数据
ResultScanner rs=table.getScanner(scan);
Result result=null;
while((result=rs.next())!=null)
{
System.out.println("1");
KeyValue[] kvs=result.raw();
for(KeyValue kv:kvs)
{
System.out.println(kv.toString());
System.out.println(Bytes.toString(kv.getValue()));
}
}
//释放ziyuan
rs.close();
table.close();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
6、首次行键值过滤器:FirstKeyColumnValueFilter
该过滤器值返回一行中第一个KeyValue对象的Key值,也就是每行只返回一个Key值。因此非常适合使用在一些行数统计上。
public void example(String tableName)
{
Configuration conf=init();
try {
HTable table=new HTable(conf, tableName);
//创建过滤器
FirstKeyOnlyFilter filter=new FirstKeyOnlyFilter();
Scan scan=new Scan();
scan.setFilter(filter);
//获取数据并遍历
ResultScanner rs=table.getScanner(scan);
Result result=null;
while((result=rs.next())!=null)
{
KeyValue[] kvs=result.raw();
for(KeyValue kv:kvs)
{
System.out.println(kv.toString());
}
}
//释放资源
rs.close();
table.close();
} catch (Exception e) {
// TODO: handle exception
}
}
7、包含结果过滤器:InclusiveStopFilter
因为Scan的扫描范围为左闭右开的,当有时候我们无法判断指定的endrow的下一个row是什么,却要必须要将endrow包含在扫描范围之内时就可以使用该过滤器,通过该过滤器,scan只需要设置startRow,在过滤器中设置endRow,扫描器就会扫描 [startRow,endRow]这个范围的数据
public void example(String tableName)
{
Configuration conf=init();
try {
HTable table=new HTable(conf, tableName);
//创建filter
InclusiveStopFilter filter=new InclusiveStopFilter(Bytes.toBytes("row-5"));
Scan scan=new Scan();
scan.setFilter(filter);
//获取数据并沾水
ResultScanner rs=table.getScanner(scan);
Result result=null;
while((result=rs.next())!=null)
{
KeyValue[] kvs=result.raw();
for(KeyValue kv:kvs)
{
System.out.println(kv.toString());
}
}
rs.close();
table.close();
} catch (Exception e) {
// TODO: handle exception
}
}
8、时间戳过滤器:TimeStampFilter(long timeStamp)
该过滤器主要是用于过滤时间戳的,即符合指定的时间戳是既可以进行返回,因此可以做到细粒度的控制数据返回。
public void example(String tableName)
{
Configuration conf=init();
try {
HTable table=new HTable(conf, tableName);
//创建过滤器
List<Long> stamps=new ArrayList<>();
stamps.add(new Long("1457019405362"));
TimestampsFilter filter=new TimestampsFilter(stamps);
Scan scan=new Scan();
scan.setFilter(filter);
//获取数据并返回
ResultScanner rs=table.getScanner(scan);
Result result=null;
while((result=rs.next())!=null)
{
KeyValue[] kvs=result.raw();
for(KeyValue kv:kvs)
{
System.out.println(kv.toString());
}
}
//释放资源
rs.close();
table.close();
} catch (Exception e) {
// TODO: handle exception
}
}
9、列计数过滤器:ColumnCountGetFilter(int n)
该过滤器只返回指定的前n个列的数据。超过 n的列的数据不进行返回。
public void example(String tableName)
{
Configuration conf=init();
try {
HTable table=new HTable(conf, tableName);
//闯进过滤器
ColumnCountGetFilter filter=new ColumnCountGetFilter(1);
Scan scan=new Scan();
scan.setFilter(filter);
//获取数据并返回
ResultScanner rs=table.getScanner(scan);
Result result=null;
while((result=rs.next())!=null)
{
KeyValue[] kvs=result.raw();
for(KeyValue kv:kvs)
{
System.out.println(kv.toString());
}
}
//
rs.close();
table.close();
} catch (Exception e) {
// TODO: handle exception
}
}
9、列分页过滤器:ColumnPaginationFilter(int limit,int off)
该过滤器对列进行分页,每次返回limit个列,并且从第off个列开始返回。因此构造函数中的两个数字是用来规定返回的其实位置和返回数据数量的。
public void example(String tableName)
{
Configuration conf=init();
try {
HTable table=new HTable(conf, tableName);
//创建扫描器
ColumnPaginationFilter filter=new ColumnPaginationFilter(1, 0);
Scan scan=new Scan();
scan.setFilter(filter);
//
ResultScanner rs=table.getScanner(scan);
Result result=null;
while((result=rs.next())!=null)
{
KeyValue[] kvs=result.raw();
for(KeyValue kv:kvs)
{
System.out.println(kv.toString());
}
}
//
rs.close();
table.close();
} catch (Exception e) {
// TODO: handle exception
}
}
10、列前缀过滤器:ColumnPrefixFilter(byte[] prefix)
该过滤器和前缀过滤器很相似,不同的是其过滤对象是针对列的,即列名不符合要求的列中的数据将被过滤掉,不返回到客户端中。
public void example(String tableName)
{
Configuration conf=init();
try {
HTable table=new HTable(conf, tableName);
//创建扫描器
ColumnPrefixColumn filter=new ColumnPrefixColumn(Bytes.toBytes("col"));
Scan scan=new Scan();
scan.setFilter(filter);
//
ResultScanner rs=table.getScanner(scan);
Result result=null;
while((result=rs.next())!=null)
{
KeyValue[] kvs=result.raw();
for(KeyValue kv:kvs)
{
System.out.println(kv.toString());
}
}
//
rs.close();
table.close();
} catch (Exception e) {
// TODO: handle exception
}
}
11、随机过滤器:RandomFilter(float chance)
过滤器拥有一个float类型的参数,该参数决定了返回数据的数量:
chance >=1 时,数据全部被返回
0< chance <1 时,按照比例随机返回数据
chance < 0时,不返回任何数据。
public void example(String tableName)
{
Configuration conf=init();
try {
HTable table=new HTable(conf, tableName);
//创建扫描器
RandomColumn filter=new RandomColumn(0.6f);
Scan scan=new Scan();
scan.setFilter(filter);
//
ResultScanner rs=table.getScanner(scan);
Result result=null;
while((result=rs.next())!=null)
{
KeyValue[] kvs=result.raw();
for(KeyValue kv:kvs)
{
System.out.println(kv.toString());
}
}
//
rs.close();
table.close();
} catch (Exception e) {
// TODO: handle exception
}
}
三、总结
过滤器由于刚推出不久,因此在版本变化过程中会出现较大的改变,因此当用户在使用过滤器时,一定要结合hbase 版本的API文档进行使用。防止出现错误使用。因为本文章并没有对每一个过滤器的详细的方法进行介绍,因此如果想要进一步了解每一个过滤器的作用,请参考HBase 1.1.2 版本的 API进行查看。