hbase_过虑器

1. 结构过滤器--FilterList

FilterList 代表一个过滤器链,它可以包含一组即将应用于目标数据集的过滤器,过滤器间具有“与” FilterList.Operator.MUST_PASS_ALL 

“或” FilterList.Operator.MUST_PASS_ONE 关系。

 

两个“或”关系的过滤器的写法:

public List<Map<String, Object>> getListByOr(String tableName, List<String> fieldNames, List<String> fieldValues) {

//数据只要满足一组过滤器中的一个就可以

FilterList list = new FilterList(Operator.MUST_PASS_ONE);

for (int i = 0; i < fieldNames.size(); ++i){

Filter filter =  new SingleColumnValueFilter(

Bytes.toBytes(HbaseUtil.FAMILYNAME),  //列族

Bytes.toBytes(fieldNames.get(i)),  //列名       

CompareOp.EQUAL,

Bytes.toBytes(fieldValues.get(i)));    

list.addFilter(filter);

}

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)

 

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

示例:

Filter filter =  new SingleColumnValueFilter(

Bytes.toBytes("prop"), // 列族

Bytes.toBytes(fieldName), // 列名       

CompareOp.EQUAL,// 条件

Bytes.toBytes(fieldValue)); // 

 

2) 第二种构造函数情况 -- 比较的关键字是比较器

ByteArrayComparable是一个基类,上面已列出了它的一些子类。

① 支持值比较的正则表达式 -- RegexStringComparator

示例代码

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

Filter filter =  new SingleColumnValueFilter(

Bytes.toBytes("prop"), // 列族

Bytes.toBytes(fieldName), // 列名       

CompareOp.EQUAL,// 条件

comp ); // 比较器

注:查出来的数据除了fieldName”my.”打头的外,还会查出没有此fieldName的字段。

目前还没找到好的方法去过滤。

 

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

SubstringComparator comp = new SubstringComparator("2013-06-1");// 包含2013-06-1的串

Filter filter =  new SingleColumnValueFilter(

Bytes.toBytes("prop"), // 列族

Bytes.toBytes(fieldName), // 列名       

CompareOp.EQUAL,// 条件

comp ); // 比较器

 

③ NullComparator

示例:

查出所有”address”字段不存在的记录

NullComparator comp = new NullComparator();

Filter filter =  new SingleColumnValueFilter(

Bytes.toBytes("prop"), // 列族

Bytes.toBytes("address"), // 列名       

CompareOp.EQUAL,// 条件

comp ); // 比较器

如果EQUAL改为NOT_EQUAL,并不是获取字段存在的记录,得到的是所有记录,因此达不到过滤的作用。

 

④ BinaryComparator

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

 

⑤ BinaryPrefixComparator

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

 

 

3. 键值元数据

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

1) 基于列族过滤数据的FamilyFilter

构造函数:

FamilyFilter(CompareFilter.CompareOp familyCompareOp, ByteArrayComparable familyComparator)

示例:

/**

 * FamilyFilter构造函数中第二个参数是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);

注意:

如果希望查找的是一个已知的列族,则使用 scan.addFamily(family)  比使用过滤器效率更高;

由于目前HBase对多列族支持不完善,所以该过滤器目前用途不大。

 

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

构造函数:

QualifierFilter(CompareFilter.CompareOp op, ByteArrayComparable qualifierComparator)

示例:

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

 

说明:

一旦涉及到列(Qualifier),HBase就只认大写字母了!

该过滤器应该比FamilyFilter更常用!

示例:查出name字段不空的记录

QualifierFilter qf = new QualifierFilter(

        CompareOp.EQUAL ,

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

        );

 

3) 基于列名前缀过滤数据的ColumnPrefixFilter  ( 该功能用QualifierFilter也能实现 )

构造函数:

ColumnPrefixFilter(byte[] prefix) 

注意:

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

示例:

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

 

4) 基于多个列名前缀过滤数据的MultipleColumnPrefixFilter

说明:

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

示例:

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

 

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

说明:

1.可用于获得一个范围的列,例如,如果你的一行中有百万个列,但是你只希望查看列名为bbbbdddd的范围

2.该方法从 HBase 0.92 版本开始引入

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

 

构造函数:

ColumnRangeFilter(

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

参数解释:

minColumn - 列范围的最小值,如果为空,则没有下限;

minColumnInclusive - 列范围是否包含minColumn

maxColumn - 列范围最大值,如果为空,则没有上限;

maxColumnInclusive - 列范围是否包含maxColumn

示例代码:

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

 

4. RowKey

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

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

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

        Scan scan = new Scan(startColumn,endColumn);

 

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

构造函数:

RowFilter(CompareFilter.CompareOp rowCompareOp, ByteArrayComparable rowComparator)

 

示例:

/**

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

 * 目标:查找  发布日期  为  2013-07-16  的数据

 */

RowFilter rf = new RowFilter(

        CompareOp.EQUAL,

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

        );

Scan scan = new Scan();

scan.setFilter(rf);

 

 

提取rowkey01结尾数据

Filter filter = new RowFilter(CompareFilter.CompareOp.EQUAL,new RegexStringComparator(".*01$"));

 

提取rowkey以包含201407的数据

Filter filter = new RowFilter(CompareFilter.CompareOp.EQUAL,new SubstringComparator("201407"));

 

 

提取rowkey123开头的数据

Filter filter = new RowFilter(CompareFilter.CompareOp.EQUAL,new BinaryPrefixComparator("123".getBytes()));

 

 

5. PageFilter

指定页面行数,返回对应行数的结果集。

需要注意的是,该过滤器并不能保证返回的结果行数小于等于指定的页面行数,因为过滤器是分别作用到各个region server的,它只能保证当前region返回的结果行数不超过指定页面行数。

构造函数:

PageFilter(long pageSize)

示例代码(从“2013-07-26”行开始,取5行):

Scan scan = new Scan();

scan.setStartRow(Bytes.toBytes("2013-07-26"));

PageFilter pf = new PageFilter(5L);

scan.setFilter(pf);

ResultScanner rs = table.getScanner(scan);

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))

                + "   Time : " + cell.getTimestamp());

    }

}  

由于该过滤器并不能保证返回的结果行数小于等于指定的页面行数,所以更好的返回指定行数的办法是ResultScanner.next(int nbRows) ,即:

    ResultScanner rs = table.getScanner(scan);

    for (Result r : rs.next(5)) {

        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))

                    + "   Time : " + cell.getTimestamp());

        }

    }  

 

6. SkipFilter

根据整行中的每个列来做过滤,只要存在一列不满足条件,整行都被过滤掉。

例如,如果一行中的所有列代表的是不同物品的重量,则真实场景下这些数值都必须大于零,我们希望将那些包含任意列值为0的行都过滤掉。

在这个情况下,我们结合ValueFilter和SkipFilter共同实现该目的:

scan.setFilter(new SkipFilter(new ValueFilter(CompareOp.NOT_EQUAL,new BinaryComparator(Bytes.toBytes(0))));

构造函数:

SkipFilter(Filter filter) 

其含义也很明了:先用filter过滤,然后使用反向排除法去过滤。

 

7. Utility--FirstKeyOnlyFilter

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

估计实战意义不大。

构造函数:

public FirstKeyOnlyFilter()

示例:

public Long getAllCount(String tableName){

Long count = 0L;

FirstKeyOnlyFilter fkof = new FirstKeyOnlyFilter();

Scan scan = new Scan();

scan.setFilter(fkof);

List<Map<String, Object>> objList = hbaseTemplate.find(tableName, scan, new RowMapper<Map<String, Object>>() {

@Override

public Map<String, Object> mapRow(Result result, int rowNum) throws Exception {

return null;

}

});

count = (long) objList.size();

return count;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值