hbase 过滤器

参考以下两个blog
https://blog.csdn.net/weixin_40861707/article/details/83340929

https://blog.csdn.net/lr131425/article/details/72676254

一. hbase shell的filter操作

  1. 不设置过滤器,全表扫描
    scan ‘表名’ //查询出某个表格内全部的数据记录
    举例 : scan ‘upos_city_qh_yushu:tb_detail_userloc_outdoor_22180822’
    查询结果如下(截取了其中一个行键的内容) :
    1
    2
    3

因为hbase的shell脚本操作十分不方便,并且不支持查看上下文,对我们使用者来说十分不友好,所以对于查询操作,我们使用诸如下面的操作进行"

举例 : echo “scan ‘upos_city_qh_yushu:tb_detail_userloc_outdoor_20180822’” | hbase shell
// 输出表格的查询结果到控制台,效果等同于在hbase shell脚本里进行查询
// 需要注意的是脚本里面包含""的话,前面需要加\进行转义
// 接下来的示例将使用两种方式进行举例,并且每条命令均经过验证
1
2
3
4
5
6
2. 按照value的值过滤 ValueFilter
scan ‘表名’, FILTER=>“ValueFilter(=,‘substring:value值’)” //查询出某个表格内列值包含指定字符串的记录
举例: upos_city_qh_yushu:tb_detail_userloc_outdoor_22180822, FILTER=>“ValueFilter(=,‘substring:6327’)”
//该命令表示查询表名 upos_city_qh_yushu:tb_detail_userloc_outdoor_22180822
里面值包含6327的记录
1
2
3
4

  1. 按照列簇进行过滤 FamilyFilter
    scan ‘表名’, FILTER=>“FamilyFilter(=,‘substring:字符串的值’)” //查询出某个表名列簇包含某个字符串的记录
    举例 : scan ‘upos_city_qh_yushu:tb_detail_userloc_outdoor_20180822’, FILTER=>“FamilyFilter(=,‘substring:l’)”

    echo “scan ‘upos_city_qh_yushu:tb_detail_userloc_outdoor_20180822’,FILTER=>“FamilyFilter(=,‘substring:l’)”” | hbase shell
    1
    2
    3
    4

  2. 按照行键进行过滤 RowFilter

    a. 过滤出行键包含某个字符串的数据记录(模糊查询)
    命令 : scan ‘表名’,FILTER=>“RowFilter(=,‘substring:字符串的值’)”
    举例 : scan ‘upos_city_qh_yushu:tb_detail_userloc_outdoor_20180822’,FILTER=>“RowFilter(=,‘substring:3040’)”

    echo “scan ‘upos_city_qh_yushu:tb_detail_userloc_outdoor_20180822’,FILTER=>“RowFilter(=,‘substring:3040’)”” | hbase shell

    b. 按照某个确定的行键进行过滤 (<,<=,=,>,>=)
    命令 : scan ‘表名’,FILTER=>“RowFilter(=,‘binary:行键值’)”
    举例 : scan ‘upos_city_qh_yushu:tb_detail_userloc_outdoor_20180822’,FILTER=>“RowFilter(=,‘binary:00_460075097670490_1534925332480’)”

    echo “scan ‘upos_city_qh_yushu:tb_detail_userloc_outdoor_20180822’,FILTER=>“RowFilter(=,‘binary:00_460075097670490_1534925332480’)”” | hbase shell
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    查询结果如下所示 : 行键为00_460075097670490_1534925332480的全部记录

<, <=, >, >= 同理

c. 按照行键前缀进行过滤 PrefixFilter
scan '表名',FILTER=>"PrefixFilter('行键前缀')" //查询出行键以某个字符串开始的记录
scan 'upos_city_qh_yushu:tb_detail_userloc_outdoor_20180822',FILTER=>"PrefixFilter('00_46007509767')"
echo "scan 'upos_city_qh_yushu:tb_detail_userloc_outdoor_20180822',FILTER=>\"PrefixFilter('00_46007509767')\"" | hbase shell

1
2
3
4
二. java api的filter操作

  1. 首先介绍一下 hbase过滤操作的一些参数

(1)比较运算符 CompareFilter.CompareOp
比较运算符用于定义比较关系,可以有以下几类值供选择:

EQUAL 相等
GREATER 大于
GREATER_OR_EQUAL 大于等于
LESS 小于
LESS_OR_EQUAL 小于等于
NOT_EQUAL 不等于

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

BinaryComparator 匹配完整字节数组
BinaryPrefixComparator 匹配字节数组前缀
BitComparator
NullComparator
RegexStringComparator 正则表达式匹配
SubstringComparator 子串匹配
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2. 设置hbase连接相关配置,获取hbase连接

/**
* 获取hbase连接的配置
* @param quorum 举例 : 127.0.0.1:2181
* @return
*/
private Configuration getConfiguration(String quorum)
{
Configuration conf = HBaseConfiguration.create();
conf.set(“hbase.zookeeper.quorum”, quorum);
conf.set(“hbase.rootdir”, “/data/hadoop/data”);
conf.set(“zookeeper.znode.parent”, “/hbase”);
return conf;
}

/**
* 获取hbase连接
* @param conf
* @return
*/
private Connection getConnection(Configuration conf)
{
Connection conn = null;
try
{
conn = ConnectionFactory.createConnection(conf);
System.out.println("获取hbase连接成功! " + conf.get(“hbase.zookeeper.quorum”) );
} catch (IOException e) {
System.out.println("获取hbase连接失败 " + e.getMessage());
}

return conn;

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
3. 获取scan对象,设置过滤条件

Table table = connection.getTable(TableName.valueOf(tableName));
// 通过上一步操作获取到的连接, 和想要查询的表名来获取table对象
Scan scan = new Scan(); // 获取scan对象, 通过该对象来进行查询

接下来就要设置过滤器来进行过滤查询:

如果过滤条件只有一种,直接使用各种Filter对象即可
过滤条件有多种,使用 :
FilterList filters = new FilterList(); // 过滤器集合
然后使用 scan.setFilter(filters); //将过滤器添加到进去
最后使用  ResultScanner rs = table.getScanner(scan); //即可获取结果集

1
2
3
4
5
6
7
8
9
10
11
java api的过滤器操作 :

a. 基于列簇的过滤器FamilyFilter
构造函数:
FamilyFilter(CompareFilter.CompareOp familyCompareOp, ByteArrayComparable familyComparator)

FamilyFilter familyFilter = new FamilyFilter(CompareOp.EQUAL , new BinaryComparator(Bytes.toBytes("info")));   
//返回有列簇info的数据

1
2
3
4
5
b. 基于列的过滤器QualifierFilter
b1. 基于列名过滤
构造函数:
QualifierFilter(CompareFilter.CompareOp op, ByteArrayComparable qualifierComparator)
举例 :
QualifierFilter qualifierFilter = new QualifierFilter(
CompareOp.EQUAL , new BinaryComparator(Bytes.toBytes(“eci”)));
// 返回包含eci列的数据
1
2
3
4
5
6
b2. 基于列名前缀过滤
构造函数:
ColumnPrefixFilter(byte[] prefix)
ColumnPrefixFilter columnPrefixFilter = new ColumnPrefixFilter(Bytes.toBytes(“i”));
//返回列名以i开头的全部数据
1
2
3
4
b3. 基于多个列名前缀过滤 MultipleColumnPrefixFilter
byte[][] bytes = new byte[][] {Bytes.toBytes(“i”), Bytes.toBytes(“eci”)};

MultipleColumnPrefixFilter multipleColumnPrefixFilter = new MultipleColumnPrefixFilter(bytes);

1
2
3
//返回所有行中以i或者eci打头的列的数据
1
c.基于行键的过滤器RowkeyFilter(主要)
c1. 行键比较过滤器
Filter filter = null;
String filterStr = “00_460075097670490_1534925332480”;

行键相等过滤器 :
filter = new PrefixFilter(Bytes.toBytes(filterStr.trim())); //返回行键内容为该指定行键的全部内容

行键不等过滤器 : 
filter = new RowFilter(CompareOp.NOT_EQUAL, new BinaryComparator(filterStr.trim().getBytes()));
//返回行键不等于该指定行键的全部内容

行键小于过滤器 :
filter = new RowFilter(CompareOp.LESS, new BinaryPrefixComparator(filterStr.trim().getBytes()));
//返回行键前缀小于等于指定行键的全部内容

行键小于等于过滤器 : 
filter = new RowFilter(CompareOp.LESS_OR_EQUAL, new BinaryPrefixComparator(filterStr.trim().getBytes()));
// 返回行键前缀小于等于该指定行键的全部内容

行键大于过滤器 : 
filter = new RowFilter(CompareOp.GREATER, new BinaryPrefixComparator(filterStr.trim().getBytes()));
// 返回行键前缀大于等于指定行键的全部内容

行键大于等于过滤器 : 
filter = new RowFilter(CompareOp.GREATER_OR_EQUAL, new BinaryPrefixComparator(filterStr.trim().getBytes()));
// 返回行键大于等于指定行键的全部内容 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
c2. 行键包含过滤器
行键包含过滤器 :
filter = new RowFilter(CompareFilter.CompareOp.EQUAL, new SubstringComparator(filterStr.trim()));
// 过滤出行键包含指定字符串的全部数据
1
2
3
c3. 通过startkey和 endkey来进行过滤

相比以上的过滤器,在结果集的数据条数大致相同的情况下,这种过滤方式的效率明显更高
在我们的业务场景里应用的最为广泛

这种方式就不是使用Filter对象了 : 

代码如下 :
String startkey = "00_460075097670490_1534925332480";
String endkey = "00_460075097670490_1534925432480"
Scan scan = new Scan();
scan.setStartRow(startkey.trim().getBytes());
scan.setStopRow(endkey.trim().getBytes());
// 查询从起始行键到结束行键的全部记录数
// 注意 : 包括起始行键和结尾行键!!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
4. 根据之前获取到的ResultScanner对象, 遍历结果集并输出结果:
ResultScanner rs = table.getScanner(scan);
for (Result result : rs) {
List cells= result.listCells();
for (Cell cell : cells) {
String row = Bytes.toString(result.getRow());
String family1 = Bytes.toString(CellUtil.cloneFamily(cell));
String qualifier = Bytes.toString(CellUtil.cloneQualifier(cell));
String value = Bytes.toString(CellUtil.cloneValue(cell));
System.out.println("[row:"+row+"],[family:"+family1+"],[qualifier:"+qualifier+"]"
+ “,[value:”+value+"],[time:"+cell.getTimestamp()+"]");
}
}

版权声明:本文为CSDN博主「new个对象先」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_40861707/article/details/83340929

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值