JAVA操作HBase过滤器

HBase中可以根据Filter进行高效过滤,基于Hbase本身提供的三维有序(主键有序、列有序、版本有序),这些Filter可以高效的完成查询过滤的任务。带有Filter条件的RPC查询请求会把Filter分发到各个RegionServer,是一个服务器端(Server-side)的过滤器,这样也可以降低网络传输的压力。

  要使用过滤器完成一个过滤的操作,至少需要两个参数。一个是抽象的操作符,Hbase提供了枚举类型的变量来表示这些抽象的操作符:LESS/LESS_OR_EQUAL/EQUAL/NOT_EUQAL等;另外一个就是具体的比较器(Comparator),代表具体的比较逻辑。

抽象操作符(比较运算符)

LESS <

LESS_OR_EQUAL <=

EQUAL =

NOT_EQUAL <>

GREATER_OR_EQUAL >=

GREATER >

NO_OP 排除所有

比较器(指定比较机制)

BinaryComparator 按字节索引顺序比较指定字节数组,采用 Bytes.compareTo(byte[])

BinaryPrefixComparator 跟前面相同,只是比较左端的数据是否相同

NullComparator 判断给定的是否为空

BitComparator 按位比较

RegexStringComparator 提供一个正则的比较器,仅支持 EQUAL 和非 EQUAL

SubstringComparator 判断提供的子串是否出现在 value 中

JAVA操作HBase过滤器

package wxs.main;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.filter.*;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;
import java.util.ArrayList;
import java.util.List;

public class Real {
    private static Configuration conf;

    static {  //如果不加大括号,就会认为conf是个未知类
        conf = HBaseConfiguration.create();
        conf.set("hbase.zookeeper.quorum","westgis102:2181,westgis103:2181," +
                "westgis104:2181,westgis105:2181,westgis106:2181,westgis107:2181," +
                "westgis108:2181");
        //根据验证没有下面这一句也可以
        //conf.set("zookeeper.znode.parent","/hbase");
    }


    public static void main(String[] args) throws Exception {
        Connection conn = ConnectionFactory.createConnection(conf);
        //Admin admin=conn.getAdmin(); //这句在这里似乎没啥作用
        Table table = conn.getTable(TableName.valueOf("Student"));

        //多个过滤器组合保证顺序要用List<Filter>
        List<Filter> filters = new ArrayList<>();

        //行键过滤器RowFilter及其过滤条件
        Filter rowFilter = new RowFilter(CompareFilter.CompareOp.GREATER,
                new BinaryComparator("01".getBytes()));
        filters.add(rowFilter);

        //列族过滤器FamilyFilter及其过滤条件
        Filter familyFilter = new FamilyFilter(CompareFilter.CompareOp.EQUAL,
                new BinaryComparator("info".getBytes()));
        filters.add(familyFilter);

        //列过滤器 QualifierFilter
        Filter qualifierFilter = new QualifierFilter(CompareFilter.CompareOp.EQUAL,
                new BinaryComparator("name".getBytes()));
        filters.add(qualifierFilter);

        //值过滤器 ValueFilter
        Filter valueFilter = new ValueFilter(CompareFilter.CompareOp.EQUAL,
                new SubstringComparator("male"));
        filters.add(valueFilter);

        //单列值过滤器 SingleColumnValueFilter ----会返回满足条件的整行
        SingleColumnValueFilter singleColumnValueFilter =
                new SingleColumnValueFilter(
                "info".getBytes(), //列簇
                "name".getBytes(), //列
                CompareFilter.CompareOp.EQUAL,
                new SubstringComparator("刘晨")
                );
        //如果不设置为 true,则那些不包含指定 column 的行也会返回
        singleColumnValueFilter.setFilterIfMissing(true);
        filters.add(singleColumnValueFilter);

        //单列值排除器 SingleColumnValueExcludeFilter
        SingleColumnValueExcludeFilter singleColumnValueExcludeFilter =
                new SingleColumnValueExcludeFilter(
                "info".getBytes(),
                "name".getBytes(),
                CompareFilter.CompareOp.EQUAL,
                new SubstringComparator("刘晨")
                );
        singleColumnValueExcludeFilter.setFilterIfMissing(true);
        filters.add(singleColumnValueExcludeFilter);

        //前缀过滤器 PrefixFilter----针对行键
        PrefixFilter prefixFilter = new PrefixFilter("0".getBytes());
        filters.add(prefixFilter);

        //列前缀过滤器 ColumnPrefixFilter
        ColumnPrefixFilter columnPrefixFilter =
                new ColumnPrefixFilter("name".getBytes());
        filters.add(columnPrefixFilter);

    /*
        //时间戳过滤器 TimestampsFilter
        List<Long> list1= new ArrayList<>();
        //list1.add(1575363754969);
        list1.add(19536375441);//emmmmmm这什么神奇的bug。。。考虑到时间戳一般会作为复合rowKey的一部分所以弃了弃了
        TimestampsFilter timestampsFilter=new TimestampsFilter(list1);
        filters.add(timestampsFilter);
     */
    
        //其实就相当于and和or的关系
        // MUST_PASS_ONE只要scan的数据行符合其中一个filter就可以返回结果
        // (但是必须扫描所有的filter),
        //另外一种MUST_PASS_ALL必须所有的filter匹配通过才能返回数据行
        // (但是只要有一个filter匹配没通过就算失败,后续的filter停止匹配)。
        FilterList filterList=new FilterList(FilterList.Operator.MUST_PASS_ALL,
                filters);

        //相当于shell中的scan
        Scan scan=new Scan();

        //将过滤条件应用于scan
        //单个过滤条件
        scan.setFilter(familyFilter);
        //多个过滤条件
        scan.setFilter(filterList);

        //将scan应用于table并获取过滤后的扫描结果
        ResultScanner resultScanner=table.getScanner(scan);

        //输出扫描结果 外层循环:逻辑行 内层循环:每个逻辑行的键值
        for (Result r:resultScanner){
            List<Cell> cells=r.listCells();
            //System.out.println(r);
            for (Cell cell:cells){
                System.out.println("Cell:"+cell+"\nvalue:"+
                        Bytes.toString(cell.getValueArray(),
                                       cell.getValueOffset(),
                                       cell.getValueLength()));
            }
        }

        //关闭scan结果和表
        resultScanner.close();
        table.close();
    }
}

参考:https://www.cnblogs.com/qingyunzong/p/8681529.html

发布了94 篇原创文章 · 获赞 20 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/helloworld0906/article/details/103367564