• Hbase中内置Filter


    TOC

    Hbase中内置Filter

    参考:

    Hbase中支持的内置Filter列表如下(在org.apache.hadoop.hbase.filter目录下)

    • DependentColumnFilter
    • FamilyFilter
    • QualifierFilter
    • RowFilter
    • ValueFilte
    • ...

    Hbase就是使用这些Filter进行查询的

    测试数据

    1、表名:“ORDER_TABLE”

    2、列簇:“user”,“order”,“item”

    image-20200730180702144

    RowFilter

    说明:筛选出匹配的所有的,支持基于行键过滤数据,可以执行精确匹配,子字符串匹配或正则表达式匹配,过滤掉不匹配的数据。

    用法:使用BinaryComparator可以筛选出具有某个行键的行,或者通过改变比较运算符来筛选出符合某一条件的多条数据

    RowFilter的使用关键在于CompareFilter.CompareOp这个内部枚举类,该类的定义如下:

    @InterfaceAudience.Public
      @InterfaceStability.Stable
      public enum CompareOp {
        /** less than */
        LESS,  // 检查是否小于比较器里的值
        /** less than or equal to */
        LESS_OR_EQUAL,  // 检查是否小于或等于比较器里的值
        /** equals */
        EQUAL,  // 检查是否等于比较器里的值
        /** not equal */
        NOT_EQUAL, // 检查是否不等于比较器里的值
        /** greater than or equal to */
        GREATER_OR_EQUAL,  // 检查是否大于或等于比较器里的值
        /** greater than */
        GREATER,  // 检查是否大于比较器里的值
        /** no operation */
        NO_OP,  // 默认返回false,因此过滤掉所有的数据
      }

    该枚举类定义了7种比较运算符,供我们扫描操作

    例如:

    Filter filter = new RowFilter(CompareFilter.CompareOp.EQUAL, new BinaryComparator(Bytes.toBytes("firstRow")));
    结果:
    KV: firstRow/item:name/1479788712670/Put/vlen=5/mvcc=0, Value: maoyi
    KV: firstRow/item:price/1479788739567/Put/vlen=3/mvcc=0, Value: 100
    KV: firstRow/item:type/1479788725903/Put/vlen=4/mvcc=0, Value: yifu
    KV: firstRow/order:num/1479788660941/Put/vlen=1/mvcc=0, Value: 1
    KV: firstRow/order:payType/1479788691846/Put/vlen=5/mvcc=0, Value: check
    KV: firstRow/order:totalPrice/1479788676517/Put/vlen=3/mvcc=0, Value: 100
    KV: firstRow/user:address/1479788610153/Put/vlen=9/mvcc=0, Value: chongqing
    KV: firstRow/user:name/1479788577571/Put/vlen=6/mvcc=0, Value: chhliu
    KV: firstRow/user:password/1479788593494/Put/vlen=6/mvcc=0, Value: 123456
    //主键/列族/列/时间戳/操作类型/   值

    从测试结果可以看出,扫描出了所有“firstRow”行的数据。

    QualifierFilter:列

    说明:该Filter是一种类似RowFilter的比较过滤器,不同之处是它用来匹配限定符而不是行键(查询每一行的这个列的数据)

    例如:

    Filter filter = new QualifierFilter(CompareFilter.CompareOp.EQUAL, new RegexStringComparator("name"));
    结果:
    KV: firstRow/item:name/1479788712670/Put/vlen=5/mvcc=0, Value: maoyi
    KV: firstRow/user:name/1479788577571/Put/vlen=6/mvcc=0, Value: chhliu
    ------------------------------------------------------------
    KV: secondRow/item:name/1479788846563/Put/vlen=4/mvcc=0, Value: kuzi
    KV: secondRow/user:name/1479788961691/Put/vlen=6/mvcc=0, Value: xyh123

    从上面的测试结果可以看出,扫描出了所有的列名为“name”的数据。

    不同键,不同列族的name都出来了

    PrefixFilter:行健的前缀值

    说明:这是RowFilter的一种特例,它基于行健的前缀值进行过滤,它相当于给扫描构造函数Scan(byte[] startRow, byte[] stopRow),提供了一个停止键,只是你不需要自己计算停止键。

    例如:

    Filter filter = new PrefixFilter(Bytes.toBytes("second"));
    结果:
    KV: secondRow/item:name/1479788846563/Put/vlen=4/mvcc=0, Value: kuzi
    KV: secondRow/item:price/1479788812565/Put/vlen=2/mvcc=0, Value: 50
    KV: secondRow/item:type/1479788825867/Put/vlen=4/mvcc=0, Value: yifu
    KV: secondRow/order:num/1479788793253/Put/vlen=1/mvcc=0, Value: 3
    KV: secondRow/order:payType/1479788873259/Put/vlen=4/mvcc=0, Value: cash
    KV: secondRow/order:totalPrice/1479788888925/Put/vlen=3/mvcc=0, Value: 150
    KV: secondRow/user:address/1479788916089/Put/vlen=7/mvcc=0, Value: chengdu
    KV: secondRow/user:name/1479788961691/Put/vlen=6/mvcc=0, Value: xyh123
    KV: secondRow/user:password/1479788935711/Put/vlen=10/mvcc=0, Value: 1234567890

    从上面的测试结果可以看出,所有“second”前缀的行的数据都被扫描出来了。

    KeyOnlyFilter:行键+列簇+列

    说明:这个Filter只会返回每行的行键+列簇+列,而不返回值,对不需要值的应用场景来说,非常实用,减少了值的传递。

    例如:

    Filter filter = new KeyOnlyFilter();
    结果:
    KV: firstRow/item:name/1479788712670/Put/vlen=0/mvcc=0, Value:
    KV: firstRow/item:price/1479788739567/Put/vlen=0/mvcc=0, Value:
    KV: firstRow/item:type/1479788725903/Put/vlen=0/mvcc=0, Value:
    KV: firstRow/order:num/1479788660941/Put/vlen=0/mvcc=0, Value:
    KV: firstRow/order:payType/1479788691846/Put/vlen=0/mvcc=0, Value:
    KV: firstRow/order:totalPrice/1479788676517/Put/vlen=0/mvcc=0, Value:
    KV: firstRow/user:address/1479788610153/Put/vlen=0/mvcc=0, Value:
    KV: firstRow/user:name/1479788577571/Put/vlen=0/mvcc=0, Value:
    KV: firstRow/user:password/1479788593494/Put/vlen=0/mvcc=0, Value:
    ------------------------------------------------------------
    KV: secondRow/item:name/1479788846563/Put/vlen=0/mvcc=0, Value:
    KV: secondRow/item:price/1479788812565/Put/vlen=0/mvcc=0, Value:
    KV: secondRow/item:type/1479788825867/Put/vlen=0/mvcc=0, Value:
    KV: secondRow/order:num/1479788793253/Put/vlen=0/mvcc=0, Value:
    KV: secondRow/order:payType/1479788873259/Put/vlen=0/mvcc=0, Value:
    KV: secondRow/order:totalPrice/1479788888925/Put/vlen=0/mvcc=0, Value:
    KV: secondRow/user:address/1479788916089/Put/vlen=0/mvcc=0, Value:
    KV: secondRow/user:name/1479788961691/Put/vlen=0/mvcc=0, Value:
    KV: secondRow/user:password/1479788935711/Put/vlen=0/mvcc=0, Value:

    从上面的测试结果,可以看出,Value对应的值都为空。

    TimestampsFilter:时间戳

    说明:该过滤器允许针对返回给客户端的时间版本进行更细粒度的控制,使用的时候,可以提供一个返回的时间戳的列表,只有与时间戳匹配的单元才可以返回。当做多行扫描或者是单行检索时,如果需要一个时间区间,可以在Get或Scan对象上使用setTimeRange()方法来实现这一点。

    例如:

    List<Long> timestamps = new ArrayList<Long>();
    timestamps.add(1479788961691L);
    timestamps.add(1479788676517L);
    timestamps.add(1479788812565L);
    Filter filter = new TimestampsFilter(timestamps);
    结果:
    KV: firstRow/order:totalPrice/1479788676517/Put/vlen=3/mvcc=0, Value: 100
    -----------------------------------------------------------
    KV: secondRow/item:price/1479788812565/Put/vlen=2/mvcc=0, Value: 50
    KV: secondRow/user:name/1479788961691/Put/vlen=6/mvcc=0, Value: xyh123

    返回了时间戳列表中对应的列数据。

    FirstKeyOnlyFilter:每一行的第一列

    说明:该Filter的作用,是找每一行的第一列数据,找到之后,就会停止扫描。

    Filter filter = new FirstKeyOnlyFilter();
    结果:
    KV: firstRow/item:name/1479788712670/Put/vlen=5/mvcc=0, Value: maoyi
    ------------------------------------------------------------
    KV: secondRow/item:name/1479788846563/Put/vlen=4/mvcc=0, Value: kuzi

    只扫描出了“firstRow”和“secondRow”的第一行数据(第一个列族的第一列)。

    ColumnPrefixFilter:列名的前缀

    说明:该Filter是按照列名的前缀来扫描单元格的,只会返回符合条件的列数据

    示例:

    Filter filter = new ColumnPrefixFilter(Bytes.toBytes("pay"));

    测试结果:

    KV: firstRow/order:payType/1479788691846/Put/vlen=5/mvcc=0, Value: check
    ------------------------------------------------------------
    KV: secondRow/order:payType/1479788873259/Put/vlen=4/mvcc=0, Value: cash

    从上面的测试结果可以看出,将列名中带“pay”前缀的列都扫描出来了。

    ValueFilter:对值进行过滤

    说明:该Filter主要是对值进行过滤,用法和RowFilter类似,只不过侧重点不同而已,针对的是单元值,使用这个过滤器可以过滤掉不符合设定标准的所有单元

    示例:

    Filter filter = new ValueFilter(CompareFilter.CompareOp.EQUAL, new BinaryComparator(Bytes.toBytes("100")));

    测试结果:

    KV: firstRow/item:price/1479788739567/Put/vlen=3/mvcc=0, Value: 100
    KV: firstRow/order:totalPrice/1479788676517/Put/vlen=3/mvcc=0, Value: 100

    从上面的测试结果中,我们可以看出,将Value为100的列都扫描出来了。

    Hbase提供的内置的Comparator

    Hbase提供的内置的Comparator:

    • BinaryComparator:会比较给定的值和扫描的值进行比对,如果一致则返回,使用Bytes.compareTo()方法比较。
    • BinaryPrefixComparator:如果扫描的值中带有给定的前缀,就会返回,使用Bytes.compareTo()方法,从左开始执行基于前缀的字节级比较示例如下:
      Filter filter = new ValueFilter(CompareFilter.CompareOp.EQUAL, new BinaryPrefixComparator(Bytes.toBytes("cheng")));
      结果:
      KV: secondRow/user:address/1479788916089/Put/vlen=7/mvcc=0, Value: chengdu
      //从测试结果可以看出,返回了前缀为“cheng”的列数据
    • BitComparator:执行按位比较。
    • NullComparator:检查给定值是否为空。
    • RegexStringComparator:把传递的值与比较器实例化时提供的正则表达式比较。
    • SubstringComparator:通过执行contains()方法,检查传递的值是否包含比较器提供的子字符串示例如下:
      Filter filter = new ValueFilter(CompareFilter.CompareOp.EQUAL, new SubstringComparator("123456"));
      结果:
      KV: firstRow/user:password/1479788593494/Put/vlen=6/mvcc=0, Value: 123456
      <hr />
      
      KV: secondRow/user:password/1479788935711/Put/vlen=10/mvcc=0, Value: 1234567890
      //从上面的测试结果中,可以看出,只要是值中包含了“123456”字符串的结果,都返回了。

    ColumnCountGetFilter

    说明:该Filter用来返回每行最多返回多少列,但返回的总数不超过设置的列数

    示例:

    Filter filter = new ColumnCountGetFilter(2);

    测试结果:

    KV: firstRow/item:name/1479788712670/Put/vlen=5/mvcc=0, Value: maoyi
    KV: firstRow/item:price/1479788739567/Put/vlen=3/mvcc=0, Value: 100

    从上面的测试结果可以看出,总共返回了第一行的2列

    SingleColumnValueFilter:根据列的值来决定这一行数据是否返回

    说明:根据列的值来决定这一行数据是否返回,落脚点在,而不是列。我们可以设置filter.setFilterIfMissing(true);如果为true,当这一列不存在时,不会返回,如果为false,当这一列不存在时,会返回所有的列信息。

    先来测试这一列存在的情况,当列存在时,无论设置成true或者是false,测试结果没有影响

    示例:

    SingleColumnValueFilter filter = new SingleColumnValueFilter(Bytes.toBytes("user"), Bytes.toBytes("name"), CompareFilter.CompareOp.EQUAL, new SubstringComparator("chh"));
    filter.setFilterIfMissing(false);// 默认情况下为false

    测试结果:

    KV: firstRow/item:name/1479788712670/Put/vlen=5/mvcc=0, Value: maoyi
    KV: firstRow/item:price/1479788739567/Put/vlen=3/mvcc=0, Value: 100
    KV: firstRow/item:type/1479788725903/Put/vlen=4/mvcc=0, Value: yifu
    KV: firstRow/order:num/1479788660941/Put/vlen=1/mvcc=0, Value: 1
    KV: firstRow/order:payType/1479788691846/Put/vlen=5/mvcc=0, Value: check
    KV: firstRow/order:totalPrice/1479788676517/Put/vlen=3/mvcc=0, Value: 100
    KV: firstRow/user:address/1479788610153/Put/vlen=9/mvcc=0, Value: chongqing
    KV: firstRow/user:name/1479788577571/Put/vlen=6/mvcc=0, Value: chhliu  //user族name列有chh前缀的值,这一行返回
    KV: firstRow/user:password/1479788593494/Put/vlen=6/mvcc=0, Value: 123456

    从上面的测试结果可以看出,当前列“name”存在,且前缀“chh”存在扫描的值“chhliu”中,而该值存在第一行中,所以返回第一行的所有数据。

    下面来看下列不存在的情况下,设置成true或者是false的区别

    示例:

    SingleColumnValueFilter filter = new SingleColumnValueFilter(Bytes.toBytes("user"), Bytes.toBytes("xyh"), CompareFilter.CompareOp.EQUAL, new SubstringComparator("chh"));
    filter.setFilterIfMissing(false);// 默认情况下为false

    测试结果如下:

    KV: firstRow/item:name/1479788712670/Put/vlen=5/mvcc=0, Value: maoyi
    KV: firstRow/item:price/1479788739567/Put/vlen=3/mvcc=0, Value: 100
    KV: firstRow/item:type/1479788725903/Put/vlen=4/mvcc=0, Value: yifu
    KV: firstRow/order:num/1479788660941/Put/vlen=1/mvcc=0, Value: 1
    KV: firstRow/order:payType/1479788691846/Put/vlen=5/mvcc=0, Value: check
    KV: firstRow/order:totalPrice/1479788676517/Put/vlen=3/mvcc=0, Value: 100
    KV: firstRow/user:address/1479788610153/Put/vlen=9/mvcc=0, Value: chongqing
    KV: firstRow/user:name/1479788577571/Put/vlen=6/mvcc=0, Value: chhliu
    KV: firstRow/user:password/1479788593494/Put/vlen=6/mvcc=0, Value: 123456
    ------------------------------------------------------------
    KV: secondRow/item:name/1479788846563/Put/vlen=4/mvcc=0, Value: kuzi
    KV: secondRow/item:price/1479788812565/Put/vlen=2/mvcc=0, Value: 50
    KV: secondRow/item:type/1479788825867/Put/vlen=4/mvcc=0, Value: yifu
    KV: secondRow/order:num/1479788793253/Put/vlen=1/mvcc=0, Value: 3
    KV: secondRow/order:payType/1479788873259/Put/vlen=4/mvcc=0, Value: cash
    KV: secondRow/order:totalPrice/1479788888925/Put/vlen=3/mvcc=0, Value: 150
    KV: secondRow/user:address/1479788916089/Put/vlen=7/mvcc=0, Value: chengdu
    KV: secondRow/user:name/1479788961691/Put/vlen=6/mvcc=0, Value: xyh123
    KV: secondRow/user:password/1479788935711/Put/vlen=10/mvcc=0, Value: 1234567890

    从上面的测试结果可以看出,当列“xyh”不存在是,设置成false时,会返回所有的行数据;

    当我们把false换成true测试时,会发现,没有返回任何数据。

    SingleColumnValueExcludeFilter

    说明:该Filter和SingleColumnValueFilter作用类似,唯一的区别在于,返回的数据不包含扫描条件的列。

    示例:

    Filter filter = new SingleColumnValueExcludeFilter(Bytes.toBytes("user"), Bytes.toBytes("name"), CompareFilter.CompareOp.EQUAL, new SubstringComparator("chh"));

    测试结果:

    KV: firstRow/item:name/1479788712670/Put/vlen=5/mvcc=0, Value: maoyi
    KV: firstRow/item:price/1479788739567/Put/vlen=3/mvcc=0, Value: 100
    KV: firstRow/item:type/1479788725903/Put/vlen=4/mvcc=0, Value: yifu
    KV: firstRow/order:num/1479788660941/Put/vlen=1/mvcc=0, Value: 1
    KV: firstRow/order:payType/1479788691846/Put/vlen=5/mvcc=0, Value: check
    KV: firstRow/order:totalPrice/1479788676517/Put/vlen=3/mvcc=0, Value: 100
    KV: firstRow/user:address/1479788610153/Put/vlen=9/mvcc=0, Value: chongqing
    KV: firstRow/user:password/1479788593494/Put/vlen=6/mvcc=0, Value: 123456

    从上面的测试结果可以看出,返回的结果总共只有8列的数据,没有扫描条件包含的那一列数据。

    FilterList

    Filter rowFilter = new RowFilter(CompareFilter.CompareOp.EQUAL, new BinaryComparator(Bytes.toBytes("firstRow"))); // OK 筛选出匹配的所有的行 
    Filter valueFilter = new ValueFilter(CompareFilter.CompareOp.EQUAL, new BinaryPrefixComparator(Bytes.toBytes("yifu")));
    List<Filter> listFilter = new ArrayList<Filter>();
    listFilter.add(rowFilter);
    listFilter.add(valueFilter);
    Filter filter = new FilterList(listFilter);

    测试结果:

    KV: firstRow/item:type/1479788725903/Put/vlen=4/mvcc=0, Value: yifu

    从上面的测试结果可以看出,firstRow和secondRow中都存在值为“yifu”,但是通过两个过滤器限定后,符合条件的只有firstRow中的“yifu”这一列。FilterList还支持多Filter的“AND”和“OR”操作,示例如下:

    Filter rowFilter = new RowFilter(CompareFilter.CompareOp.EQUAL, new BinaryComparator(Bytes.toBytes("firstRow"))); // OK 筛选出匹配的所有的行 
    Filter valueFilter = new ValueFilter(CompareFilter.CompareOp.EQUAL, new BinaryPrefixComparator(Bytes.toBytes("yifu")));
    List<Filter> listFilter = new ArrayList<Filter>();
    listFilter.add(rowFilter);
    listFilter.add(valueFilter);
    Filter filter = new FilterList(FilterList.Operator.MUST_PASS_ONE, listFilter);
    //MUST_PASS_ONE or

    测试结果如下:

    KV: firstRow/item:name/1479788712670/Put/vlen=5/mvcc=0, Value: maoyi
    KV: firstRow/item:price/1479788739567/Put/vlen=3/mvcc=0, Value: 100
    KV: firstRow/item:type/1479788725903/Put/vlen=4/mvcc=0, Value: yifu
    KV: firstRow/order:num/1479788660941/Put/vlen=1/mvcc=0, Value: 1
    KV: firstRow/order:payType/1479788691846/Put/vlen=5/mvcc=0, Value: check
    KV: firstRow/order:totalPrice/1479788676517/Put/vlen=3/mvcc=0, Value: 100
    KV: firstRow/user:address/1479788610153/Put/vlen=9/mvcc=0, Value: chongqing
    KV: firstRow/user:name/1479788577571/Put/vlen=6/mvcc=0, Value: chhliu
    KV: firstRow/user:password/1479788593494/Put/vlen=6/mvcc=0, Value: 123456
    ------------------------------------------------------------
    KV: secondRow/item:type/1479788825867/Put/vlen=4/mvcc=0, Value: yifu

    “AND”还是“OR”通过``FilterList.Operator.MUST_PASS_ONE来指定,如果是MUST_PASS_ONR,则是“OR”的关系,如果是MUST_PASS_ALL`,则是“AND”的关系,如果不传入这个参数,则默认为“AND”的关系。上面的测试中,使用的是“OR”的关系,也就是说,只要满足“firstRow”或者是“yifu”中的任意一个条件,都会被扫描出来。





  • 相关阅读:
    【Python】异常
    【Python】面向对象
    【Python】文件操作
    【Python】函数
    【Python】介绍以及环境搭建
    【Java】阿里巴巴开发规范手册
    【Java】NIO
    【Java】JUC
    【Git】国内的项目托管网站-码云
    【Git】在 Idea 中使用 Git
  • 原文地址:https://www.cnblogs.com/ziyue7575/p/f90361b1223bd8fdf96dd8a3e130e348.html
Copyright © 2020-2023  润新知