hbase几大过滤器

Hbase几大Filters


1、Comparision Filters 比较过滤器


1.1 RowFilter (过滤row,例如RowFilter(CompareOp.LESS_OR_EQUAL, new BinaryComparator(Bytes.toBytes("pbrry"))),返回按字母排序在pbrry之前的那些row的内容)
1.2 FamilyFilter (过滤的对象是family的名字,如FamilyFilter(CompareOp.LESS_OR_EQUAL, new BinaryComparator(Bytes.toBytes("jbrry"))),返回按字母排序在jbrry之前的那些family对应的Qualifier,value)
1.3 QualifierFilter (过滤的对象是Qualifier的名字,如QualifierFilter(CompareOp.LESS_OR_EQUAL, new BinaryComparator(Bytes.toBytes("jbrry"))),返回按字母排序在jbrry之前的那些Qualifier对应的value)
1.4 ValueFilter (过滤的对象是所有的value,与SingleColumnValueFilter不同的是SingleColumnValueFilter过滤指定的列)
1.5 DependentColumnFilter (该过滤器有两个参数:family和Qualifier,尝试找到该列所在的每一行,并返回该行具有相同时间戳的全部键值对。
如果某一行不包含指定的列,则该行的任何键值对都不返回,该过滤器还可以有一个可选的布尔参数-如果为true,从属的列不返回;该过滤器还可以有两个可选的参数--一个比较操作符和一个值比较器,用于family和Qualifier
的进一步检查,如果从属的列找到,其值还必须通过值检查,然后就是时间戳必须考虑)


2、Dedicated Filters 专用过滤器


2.1 SingleColumnValueFilter (过滤某family的Qualifier的value,value >,<,>=,<=,=,<>某给定的值,通常用在value是数字的情况下,=,<>也可用于字符串)
2.2 SingleColumnValueExcludeFilter (SingleColumnValueFilter的补充版,选择输出的Qualifier与过滤的条件用到的Qualifier不同时选择这种过滤方法会更高效)
2.3 PrefixFilter  (以raw字符前缀为过滤条件)
2.3.1 ColumnPrefixFilter(以表中的family的Qualifier为过滤对象,例如students有info:score,info:age,job:salary,ColumnPrefixFilter("s")就会把info:score,job:salary给查出来)
2.3.2 MultipleColumnPrefixFilter(功能与ColumnPrefixFilter类似,只是若要统计Qualifier即有以s开头的,又有以a开头的,就用MultipleColumnPrefixFilter)
2.3.3 InclusiveStopFilter (因为hbase的scan包含start-row不包含stop-row 如果使用这个过滤器我们可以包含stop-row)
2.4 PageFilter (获取前几条记录,PageFilter(20)是获取前20条记录)
2.5 KeyOnlyFilter (只查有哪些family和Qualifier,不显示value,就是普通的scan,把value值忽略掉)
2.6 FirstKeyOnlyFilter(只查第一个family:Qualifier,value,用于在row count的时候提高效率)
2.7 TimestampsFilter (给定long数组,数组里填上timestamps,filter后返回timestamps在给定的数组范围内的)
2.8 RandomRowFilter (给定一个概率,filter后返回任意的family:Qualifier,value)


3、Decorating Filters  包装类过滤器,此类过滤器要通过包装其他的过滤器才有意义,是其他过滤器的一种加强


3.1 SkipFilter (与ValueFilter结合使用,如某个表里面的值全是重量,我们想要返回没有重量为零的raw,实现步骤:先定义一个ValueFilter,值不等于0,然后用SkipFilter包装ValueFilter,
例如重量为0的raw叫mical,单单用ValueFilter除了返回其他的raw以外也会返回mical其他的family和Qualifier的值,只要值不为零,用SkipFilter包装后就不回返回mical的任何信息,若用SingleColumnValueFilter,则用SkipFilter包装跟不用是一样的效果)

3.2 WhileMatchFilters (按raw的排序查,可与ValueFilter结合用,也可以与SingleColumnValueExcludeFilter结合用,只要找到不匹配的就不在找下去)
相当于while循环过滤,查到不匹配的就退出



以上是HBASE API实现,现在看看HBase shell


1)SingleColumnValueFilter可以用AND和OR,其中OR逻辑正确,以下hbase shell与select * from test_row_key where (time_id='201206' or area_id='730')等价
scan 'test_row_key', {COLUMNS => ['cf:TIME_ID','cf:AREA_ID','cf:INDEX1'], FILTER => "(SingleColumnValueFilter('cf', 'TIME_ID', =, 'binary:201206')) OR (SingleColumnValueFilter('cf', 'AREA_ID', =, 'binary:730'))" }


注意:hbase shell不支持((A or B)and C),即:
select * from test_row_key where (time_id='201206' or area_id='730') and area_id='731'与
scan 'test_row_key', {COLUMNS => ['cf:TIME_ID','cf:AREA_ID','cf:INDEX1'], FILTER => "((SingleColumnValueFilter('cf', 'TIME_ID', =, 'binary:201206')) OR (SingleColumnValueFilter('cf', 'AREA_ID', =, 'binary:730')))AND (SingleColumnValueFilter('cf', 'AREA_ID', =, 'binary:731'))" }不等价,查出结果与期望不同,
也不完全一定不支持 ((A or B)and C) 或者是(A or(B and C),例如以下两个脚本就能获得期望值:
scan 'students', {COLUMNS => ['info:age','info:score','job:salary'], FILTER => "((SingleColumnValueFilter('info', 'age', =, 'binary:22')) OR (SingleColumnValueFilter('info', 'score', =, 'binary:21'))) OR ((SingleColumnValueFilter('job', 'salary', =, 'binary:30')) AND (SingleColumnValueFilter('info', 'score', =, 'binary:39')))" } //正确
scan 'students', {COLUMNS => ['info:age','info:score','job:salary'], FILTER => "(SingleColumnValueFilter('info', 'age', =, 'binary:22')) OR ((SingleColumnValueFilter('job', 'salary', =, 'binary:30')) AND (SingleColumnValueFilter('info', 'score', =, 'binary:39')))" } //正确


2)SingleColumnValueExcludeFilter与SingleColumnValueFilter的区别
SingleColumnValueExcludeFilter只统计filter过滤条件中没有的column,且效率很高
例如:
hbase(main):080:0> scan 'test_row_key', {COLUMNS => ['cf:AREA_ID','cf:INDEX1'], FILTER => "(SingleColumnValueExcludeFilter('cf', 'TIME_ID', =, 'binary:201206')) AND (SingleColumnValueExcludeFilter('cf', 'AREA_ID', =, 'binary:730'))" }
ROW                        COLUMN+CELL
 row_key_1                 column=cf:INDEX1, timestamp=1363820270626, value=201206730
 row_key_3                 column=cf:INDEX1, timestamp=1363820271110, value=201207730


hbase(main):081:0> scan 'test_row_key', {COLUMNS => ['cf:AREA_ID','cf:INDEX1'], FILTER => "(SingleColumnValueFilter('cf', 'TIME_ID', =, 'binary:201206')) AND (SingleColumnValueFilter('cf', 'AREA_ID', =, 'binary:730'))" }
ROW                        COLUMN+CELL
 row_key_1                 column=cf:AREA_ID, timestamp=1363820270491, value=730
 row_key_1                 column=cf:INDEX1, timestamp=1363820270626, value=201206730
 row_key_3                 column=cf:AREA_ID, timestamp=1363820271076, value=730
 row_key_3                 column=cf:INDEX1, timestamp=1363820271110, value=201207730
 
3)scan有COLUMNS条件时必须包含所有SingleColumnValueFilter中提到的字段才能确保结果集无误, 否则返回的结果集就可能会有问题;
在COLUMNS中包含SingleColumnValueFilter中提到的第1个字段结果正确,只包含第2个字段结果就不正确
FILTER条件的顺序没有影响


4)对于有多个family的表的情况:
同单独的family情况一样,scan有COLUMNS条件时必须包含所有SingleColumnValueFilter中提到的字段才能确保结果集无误, 否则返回的结果集就可能会有问题;也就是说SCAN的COLUMNS条件包含的字段集合要大于等于SingleColumnValueFilter中提到的字段结合
对于多family的情况,SingleColumnValueFilter中涉及到的family:column,若hbase表里面有某一个rowkey没有那个family,则无论什么情况,没有那个family的rowkey的所有值都会被查出来
hbase(main):036:0> scan 'students'
ROW                   COLUMN+CELL
 anglea               column=info:age, timestamp=1363693222317, value=22
 anglea               column=info:score, timestamp=1363693222081, value=21
 anglea               column=job:salary, timestamp=1363817390161, value=40
 mical                column=info:age, timestamp=1363908134018, value=19
 mical                column=info:score, timestamp=1363908134128, value=23
 mical                column=job:salary, timestamp=1363908136008, value=0
 nancy                column=info:age, timestamp=1363828420081, value=25
 nancy                column=info:score, timestamp=1363827479073, value=39
 nancy                column=job:salary, timestamp=1363693224574, value=30
 parry                column=info:age, timestamp=1363903322020, value=17
 parry                column=info:score, timestamp=1363903322293, value=50
 parry                column=job:salary, timestamp=1363903322334, value=30
 perry                column=info:age, timestamp=1363903322392, value=18
 perry                column=info:score, timestamp=1363903322485, value=70
 perry                column=job:salary, timestamp=1363903324337, value=60
 scutshuxue           column=info:age, timestamp=1363693222417, value=26
 scutshuxue           column=info:score, timestamp=1363693222237, value=25
 vicdd                column=info:age, timestamp=1363887601826, value=16
 vicdd                column=info:score, timestamp=1363887705348, value=60
 vicdd                column=job:salary, timestamp=1363887705533, value=40
 vicee                column=info:age, timestamp=1363887705601, value=17
 vicee                column=info:score, timestamp=1363887705663, value=80
 vicee                column=job:salary, timestamp=1363887707446, value=50
 vicky                column=info:age, timestamp=1363693222359, value=24
 vicky                column=info:score, timestamp=1363693222139, value=23
 vicky                column=job:salary, timestamp=1363817501725, value=50


scan 'students', {COLUMNS => ['info:age','info:score','job:salary'], FILTER => "(SingleColumnValueFilter('info', 'age', =, 'binary:22')) AND (SingleColumnValueFilter('job', 'salary', =, 'binary:40'))" } --结果正确
scan 'students', {COLUMNS => ['info:age','info:score','job:salary'], FILTER => "(SingleColumnValueFilter('info', 'age', =, 'binary:22')) OR (SingleColumnValueFilter('job', 'salary', =, 'binary:30'))" } --结果错误,
scutshuxue也查出来了,可能原因:nancy没有info:age项,过滤异常,验证:put 'students','nancy','info:age','25' 结果还是一样,说明错误可能原因是scutshuxue没有job:salary 再验证:put 'students','scutshuxue','job:salary','40' --结果正常了,
若用HBASE PAI实现,filter.setFilterIfMissing(true);可以忽略掉scutshuxue没有job:salary,找不到的字段不展示出来

猜你喜欢

转载自blog.csdn.net/gyxinguan/article/details/79022980