hbase过滤器

引言 -- 参数基础

1. 结构(Structural)过滤器--FilterList

2.列值过滤器--SingleColumnValueFilter

          2.1.第一种构造函数情况 -- 比较的关键字是字符数组

          2.2.第二种构造函数情况 -- 比较的关键字是比较器ByteArrayComparable

3.键值元数据

          3.1. 基于列族过滤数据的FamilyFilter

          3.2. 基于限定符Qualifier(列)过滤数据的QualifierFilter

          3.3. 基于列名(即Qualifier)前缀过滤数据的ColumnPrefixFilter

          3.4. 基于多个列名(即Qualifier)前缀过滤数据的MultipleColumnPrefixFilter

          3.5. 基于列范围(不是行范围)过滤数据ColumnRangeFilter

4. RowKey

5. Utility--FirstKeyOnlyFilter

6. 取得查询结果

有两个参数类在各类Filter中经常出现,统一介绍下:

(1)比较运算符  CompareFilter.CompareOp

比较运算符用于定义比较关系, 可以有以下几类值供选择:

EQUAL                                  相等
GREATER                              大于
GREATER_OR_EQUAL           大于等于
LESS                                      小于
LESS_OR_EQUAL                  小于等于
NOT_EQUAL                        不等于
(2)比较器   ByteArrayComparable

通过比较器可以实现多样化目标匹配效果,比较器 有以下子类可以使用:

BinaryComparator                   匹配完整字节数组 
BinaryPrefixComparator     匹配字节数组前缀 
BitComparator
NullComparator
RegexStringComparator    正则表达式匹配
SubstringComparator        子串匹配
1. 结构(Structural)过滤器-- FilterList

FilterList  代表一个 过滤器链 ,它可以包含一组即将应用于目标数据集的过滤器 ,过滤器间具有“与”   FilterList.Operator.MUST_PASS_ ALL   和“或”   FilterList.Operator.MUST_PASS_ ONE   关系。

官网实例代码, 两个 “ 或” 关系的 过滤器 的写法:

FilterList list = new FilterList(FilterList.Operator.MUST_PASS_ONE);   //数据只要满足一组过滤器中的一个就可以

SingleColumnValueFilter filter1 = new SingleColumnValueFilter(

column,

CompareOp.EQUAL,

Bytes.toBytes("my value")

list.add(filter1);

SingleColumnValueFilter filter2 = new SingleColumnValueFilter(

column,

CompareOp.EQUAL,

Bytes.toBytes("my other value")

list.add(filter2);

Scan scan = new Scan();

scan.setFilter(list);

2. 列值过滤器-- SingleColumnValueFilter

SingleColumnValueFilter  用于测试 列值 相等 (CompareOp.EQUAL ), 不等 (CompareOp.NOT_EQUAL),或单侧范围 (e.g., CompareOp.GREATER) 。

构造函数:

(1)比较的关键字是一个 字符数组

SingleColumnValueFilter(byte[] family, byte[] qualifier, CompareFilter.CompareOp compareOp, byte[] value)

(2)比较的关键字是一个 比较器 (比较器下一小节做介绍)

SingleColumnValueFilter(byte[] family, byte[] qualifier, CompareFilter.CompareOp compareOp,

ByteArrayComparable comparator

)
2.1.第一种构造函数情况 -- 比较的关键字是字符数组

官网示例代码 , 检查列值和字符串'my value' 相等:

SingleColumnValueFilter filter = new SingleColumnValueFilter(

column,

CompareOp.EQUAL,

Bytes.toBytes("my value")

scan.setFilter(filter);

个人实测代码:

        HTable table = HBaseDAO. getHTable ( "147patents" );

        FilterList filterList =  new  FilterList(FilterList.Operator. MUST_PASS_ALL );

 
        SingleColumnValueFilter filter =  new  SingleColumnValueFilter(

                Bytes. toBytes ( "patentinfo" ),

                Bytes. toBytes ( "CREATE_TIME" ),

                CompareOp. EQUAL ,

                Bytes. toBytes ( " 2013-06-08 " )

                );

        filterList.addFilter(filter);

        Scan scan =  new  Scan();

        scan.setFilter(filterList);

        ResultScanner rs = table.getScanner(scan);

         for  (Result r : rs) {

            System. out .println( "Scan: "  + r);

        }

        table.close();

 
注意: 还是大写问题,HBase的列名必须大写!

2.2.第二种构造函数情况 -- 比较的关键字是比较器 ByteArrayComparable

该章节主要是针对 SingleColumnValueFilter的 第二种构造函数使用情况做了一些举例:

(1) 支持值比较的 正则表达式  --  RegexStringComparator

官网示例代码 :

RegexStringComparator comp  = new  RegexStringComparator ("my.");   //任意以my打头的值

SingleColumnValueFilter filter = new SingleColumnValueFilter(

column,

CompareOp.EQUAL,

comp

scan.setFilter(filter);

个人实测代码:

        HTable table = HBaseDAO. getHTable ( "147patents" );

        FilterList filterList =  new  FilterList(FilterList.Operator. MUST_PASS_ALL );

       

         RegexStringComparator comp =  new  RegexStringComparator( "2013-06-1." );

       

        SingleColumnValueFilter filter =  new  SingleColumnValueFilter(

                Bytes. toBytes ( "patentinfo" ),

                Bytes. toBytes ( "CREATE_TIME" ),

                CompareOp. EQUAL ,

                 comp

                );

        filterList.addFilter(filter);

        Scan scan =  new  Scan();

        scan.setFilter(filterList);

        ResultScanner rs = table.getScanner(scan);

         for  (Result r : rs) {

            System. out .println( "Scan: "  + r);

        }

        table.close();

 
(2) 检测一个子串是否存在于值中( 大小写不敏感 ) -- SubstringComparator

官网示例代码:

SubstringComparator comp = new SubstringComparator ("y val");   // looking for 'my value'

SingleColumnValueFilter filter = new SingleColumnValueFilter(

column,

CompareOp.EQUAL,

scan.setFilter(filter);

个人实测代码:

        HTable table = HBaseDAO. getHTable ( "147patents" );

        FilterList filterList =  new  FilterList(FilterList.Operator. MUST_PASS_ALL );

       

//        RegexStringComparator  comp  = new RegexStringComparator("2013-06-1.");

         SubstringComparator comp =  new  SubstringComparator( "2013-06-1" );

       

        SingleColumnValueFilter filter =  new  SingleColumnValueFilter(

                Bytes. toBytes ( "patentinfo" ),

                Bytes. toBytes ( "CREATE_TIME" ),

                CompareOp. EQUAL ,

                comp

                );

        filterList.addFilter(filter);

        Scan scan =  new  Scan();

        scan.setFilter(filterList);

        ResultScanner rs = table.getScanner(scan);

         for  (Result r : rs) {

            System. out .println( "Scan: "  + r);

        }

        table.close();

 

(3)BinaryComparator

二进制比较器,用得较少,有需要请自行查阅官网:http://hbase.apache.org/apidocs/org/apache/hadoop/hbase/filter/BinaryComparator.html

(4)BinaryPrefixComparator

二进制前缀比较器 ,用得较少 ,有需要请自行查阅官网: http://hbase.apache.org/apidocs/org/apache/hadoop/hbase/filter/BinaryPrefixComparator.html

3. 键值元数据
由于HBase 采用 键值对 保存内部数据, 键值 元数据 过滤器 评估一行的 键 (ColumnFamily:Qualifiers) 是否存在  , 对应前节所述值的情况。

3.1. 基于 列族 过滤数据的 FamilyFilter

构造函数:

FamilyFilter(CompareFilter.CompareOp familyCompareOp, ByteArrayComparable familyComparator)

个人实测代码:

        HTable table = HBaseDAO. getHTable ( "147patents" );

         /**

         * FamilyFilter构造函数中第二个参数是ByteArrayComparable类型

         * ByteArrayComparable类参见“引言-参数基础”章节

         * 下面仅以最可能用到的BinaryComparator、BinaryPrefixComparator举例:

         */

        FamilyFilter  ff  =  new  FamilyFilter(

                CompareFilter.CompareOp. EQUAL  ,

                 new  BinaryComparator(Bytes. toBytes ( "pat" ))    //表中不存在pat列族,过滤结果为空

                );

        FamilyFilter ff1 =  new  FamilyFilter(

                CompareFilter.CompareOp. EQUAL  ,

                 new  BinaryPrefixComparator(Bytes. toBytes ( "pat" ))    //表中存在以pat打头的列族 patentinfo ,过滤结果为该列族所有行

                );

        Scan scan =  new  Scan();

        scan.setFilter(ff1);

        ResultScanner rs = table.getScanner(scan);

 

注意:

如果希望查找的是一个已知的列族,则使用  scan.addFamily( family)    比使用过滤器效率更高;
由于目前HBase对多列族支持不完善,所以该过滤器目前用途不大。
3.2.  基于限定符Qualifier(列)过滤数据 的 QualifierFilter

构造函数:

QualifierFilter(CompareFilter.CompareOp op, ByteArrayComparable qualifierComparator)

个人实测代码:

        HTable table = HBaseDAO. getHTable ( "147patents" );

         /**

         * QualifierFilter构造函数中第二个参数是ByteArrayComparable类型

         * ByteArrayComparable类有以下子类可以使用:

         * *******************************************

         * BinaryComparator  匹配完整字节数组,

         * BinaryPrefixComparator  匹配开始的部分字节数组,

         * BitComparator,

         * NullComparator,

         * RegexStringComparator,   正则表达式匹配

         * SubstringComparator

         * *******************************************

         * 下面仅以最可能用到的BinaryComparator、BinaryPrefixComparator举例:

         */

        QualifierFilter  ff  =  new  QualifierFilter(

                CompareFilter.CompareOp. EQUAL  ,

                 new  BinaryComparator(Bytes. toBytes ( "belong" ))    //表中不存在belong列,过滤结果为空

                );

        QualifierFilter ff1 =  new  QualifierFilter(

                CompareFilter.CompareOp. EQUAL  ,

                 new  BinaryPrefixComparator(Bytes. toBytes ( "BELONG" ))    //表中存在以BELONG打头的列BELONG_SITE,过滤结果为所有行的该列数据

                );

        Scan scan =  new  Scan();

        scan.setFilter(ff1);

        ResultScanner rs = table.getScanner(scan);

 
说明:

一旦涉及到列(Qualifier),HBase就只认大写字母了!
该过滤器应该比 FamilyFilter更常用!
3.3.  基于 列名(即Qualifier) 前缀 过滤数据的 ColumnPrefixFilter   ( 该功能用 QualifierFilter也能实现 )

构造函数:

ColumnPrefixFilter(byte[] prefix)

注意:

一个列名是可以出现在多个列族中的,该过滤器将返回所有列族中匹配的列。

官网示例代码,查找所有"abc "打头的列:

HTableInterface t = ...;

byte[] row = ...;

byte[] family = ...;

byte[] prefix = Bytes.toBytes("abc");

Scan scan = new Scan(row, row); // (optional) limit to one row

scan.addFamily(family); // (optional) limit to one family

Filter f = new ColumnPrefixFilter(prefix);

scan.setFilter(f);

scan.setBatch(10); // set this if there could be many columns returned

ResultScanner rs = t.getScanner(scan);

for (Result r = rs.next(); r != null; r = rs.next()) {

for (KeyValue kv : r.raw()) {

// each kv represents a column

}

}

rs.close();

个人实测代码:

        HTable table = HBaseDAO. getHTable ( "147patents" );


         //返回所有行中以BELONG打头的列的数据

 
        ColumnPrefixFilter ff1 =  new  ColumnPrefixFilter(Bytes. toBytes ( "BELONG" ));

        Scan scan =  new  Scan();

        scan.setFilter(ff1);

        ResultScanner rs = table.getScanner(scan);

 
3.4.  基于 多个 列名(即Qualifier) 前缀 过滤数据的 MultipleColumnPrefixFilter

说明:

MultipleColumnPrefixFilter 和 ColumnPrefixFilter 行为差不多,但可以指定 多个前缀 。

官方示例代码,查找所有"abc"或"xyz"打头的列:

HTableInterface t = ...;

byte[] row = ...;

byte[] family = ...;

byte[][] prefixes = new byte[][] {Bytes.toBytes("abc"), Bytes.toBytes("xyz")};

Scan scan = new Scan(row, row); // (optional) limit to one row

scan.addFamily(family); // (optional) limit to one family

Filter f = new MultipleColumnPrefixFilter(prefixes);

scan.setFilter(f);

scan.setBatch(10); // set this if there could be many columns returned

ResultScanner rs = t.getScanner(scan);

for (Result r = rs.next(); r != null; r = rs.next()) {

for (KeyValue kv : r.raw()) {

// each kv represents a column

}

}

rs.close();

个人实测代码:

        HTable table = HBaseDAO. getHTable ( "147patents" );

       

         byte [][] prefixes =  new   byte [][] {Bytes. toBytes ( "BELONG" ), Bytes. toBytes ( "CREATE" )};

         //返回所有行中以BELONG或者CREATE打头的列的数据

        MultipleColumnPrefixFilter ff =  new  MultipleColumnPrefixFilter(prefixes);

        Scan scan =  new  Scan();

        scan.setFilter(ff);

        ResultScanner rs = table.getScanner(scan);

 
3.5.  基于 列范围 (不是行范围)过滤数据 ColumnRangeFilter

说明:

可用于获得一个范围的列,例如,如果你的一行中有百万个列,但是你只希望查看列名为bbbb到dddd的范围
该方法从 HBase 0.92 版本开始引入
一个列名是可以出现在多个列族中的,该过滤器将返回所有列族中匹配的列

构造函数:

ColumnRangeFilter(byte[] minColumn, boolean minColumnInclusive, byte[] maxColumn, boolean maxColumnInclusive)

参数解释:

minColumn - 列范围的最小值,如果为空,则没有下限;
minColumnInclusive - 列范围是否包含minColumn   ;
maxColumn - 列范围最大值,如果为空,则没有上限;
maxColumnInclusive - 列范围是否包含 maxColumn  。
官网示例代码,查找列名在" bbbb"到"dddd"范围的数据 :

HTableInterface t = ...;

byte[] row = ...;

byte[] family = ...;

byte[] startColumn = Bytes.toBytes("bbbb");

byte[] endColumn = Bytes.toBytes("bbdd");

Scan scan = new Scan(row, row); // (optional) limit to one row

scan.addFamily(family); // (optional) limit to one family

Filter f = new ColumnRangeFilter(startColumn, true, endColumn, true);

scan.setFilter(f);

scan.setBatch(10); // set this if there could be many columns returned

ResultScanner rs = t.getScanner(scan);

for (Result r = rs.next(); r != null; r = rs.next()) {

for (KeyValue kv : r.raw()) {

// each kv represents a column

}

}

rs.close();

个人实测代码:

        HTable table = HBaseDAO. getHTable ( "147patents" );

       

         byte [] startColumn = Bytes. toBytes ( "C" );

         byte [] endColumn = Bytes. toBytes ( "D" );

         //返回所有列中从C到D打头的范围的数据,实际返回类似CREATOR、CREATE_TIME、CHANNEL_CODE等列的数据

        ColumnRangeFilter ff =  new  ColumnRangeFilter(startColumn,  true , endColumn,  true );

       

        Scan scan =  new  Scan();

        scan.setFilter(ff);

        ResultScanner rs = table.getScanner(scan);

 
4. RowKey

当需要 根据行键特征 查找一个范围的行数据时,使用 Scan的 startRow和stopRow 会更高效,但是, startRow和stopRow 只能匹配行键的开始字符 ,而不能匹配中间包含的字符 :

         byte [] startColumn = Bytes. toBytes ( "aaa" );

         byte [] endColumn = Bytes. toBytes ( "bbb" );

        Scan scan =  new  Scan(startColumn,endColumn);

当需要针对行键进行更复杂的过滤时,可以使用 RowFilter:

构造函数:

RowFilter(CompareFilter.CompareOp rowCompareOp, ByteArrayComparable rowComparator)

参数解释 参见“引言-参数基础”章节。

个人实测代码:

        HTable table = HBaseDAO. getHTable ( "147patents" );

         /**

         *  rowkey 格式为: 创建日期_ 发布日期 _ID_TITLE

         *  目标:查找   发布日期   在  2013 - 07 - 10  到  2013 - 07 - 11  之间的数据

         */

        RowFilter rf =  new  RowFilter(

                CompareFilter.CompareOp. EQUAL  ,

                 new  SubstringComparator( "_2013-07-16_" )  

                );

        Scan scan =  new  Scan();

        scan.setFilter(rf);

        ResultScanner rs = table.getScanner(scan);

 
注意:
测试过程中尝试通过组合使用两个RowFilter( CompareFilter.CompareOp参数分别为 GREATER_OR_EQUAL 和 LESS_OR_EQUAL ),和 SubstringComparator, 过滤找出指定发布时间范围内的数据,但结果比较意外,不是预想的数据,估计比较运算符 GREATER_OR_EQUAL 和 LESS_OR_EQUAL 和比较器 SubstringComparator组合使用效果不太好,慎用。

5. Utility- - FirstKeyOnlyFilter

该过滤器仅仅返回每一行中的第一个cell的值, 可以用于高效的执行行数统计操作。

估计实战意义不大。

构造函数:

public FirstKeyOnlyFilter()

个人实测代码:

        HTable table = HBaseDAO. getHTable ( "147patents" );

        FirstKeyOnlyFilter fkof =  new  FirstKeyOnlyFilter();

        Scan scan =  new  Scan();

        scan.setFilter(fkof);

        ResultScanner rs = table.getScanner(scan);

 
6. 取得查询结果

无论是官网的 Ref Guide还是网上流传的大部分博客中,输出查询结果的代码都是:

for (Result r = rs.next(); r != null; r = rs.next()) {

for (KeyValue kv : r.raw()) {

// each kv represents a column

}

}

但查看最新的API可知Result实例的raw()方法已经不建议使用了:

raw()  Deprecated.  as of 0.96, use rawCells()

0.96以后版本正确的获取结果代码如下:

         for  (Result r : rs) {

             for  (Cell cell : r.rawCells()) {

                System. out .println(

                         "Rowkey : " +Bytes. toString ( r.getRow() )+

                         "Familiy:Quilifier : " +Bytes. toString ( CellUtil. cloneQualifier (cell))+

                         "Value : " +Bytes. toString ( CellUtil. cloneValue (cell))

                        );

            }

        }

 

你可能感兴趣的:(hbase过滤器)