HBase过滤器,
业务应用上需要按字段的值过滤,值若是数字需要比较大小,若是字符串需要模糊匹配,或者是按枚举的清单过滤,至于查找的字段只需要列举出来就行了。 HBase 可以实现过滤row,family,Qualifier的名字,也可以过滤所有的value值 比较法有:字符串完全匹配,完全不匹配,按字母排序比大小,正则表达式等, 也可以实现按某个family,Qualifier指定的value过滤 实现按所有raw的前缀过滤,按family的Qualifier名字的前缀过滤,或实现family的Qualifier名字多种前缀过滤, 也可以实现只获取前几行 也可以用FilterList实现多个条件共同作用几大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 2 row(s) in 0.5210 seconds
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 2 row(s) in 0.0270 seconds 3)scan有COLUMNS条件时必须包含所有SingleColumnValueFilter中提到的字段才能确保结果集无误, 否则返回的结果集就可能会有问题; 在COLUMNS中包含SingleColumnValueFilter中提到的第1个字段结果正确,只包含第2个字段结果就不正确 FILTER条件的顺序没有影响 3)对于有多个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,找不到的字段不展示出来
本站文章为和通数据库网友分享或者投稿,欢迎任何形式的转载,但请务必注明出处.
同时文章内容如有侵犯了您的权益,请联系QQ:970679559,我们会在尽快处理。