1. 程式人生 > 資訊 >歌爾萬魔帶飛、供貨華米 OV,TWS 耳機鋰電池廠商成功過會

歌爾萬魔帶飛、供貨華米 OV,TWS 耳機鋰電池廠商成功過會

1. 過濾器

要完成一個過濾的操作,至少需要兩個引數。一個是抽象的操作符,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 中

2. 比較過濾器

2.1 行鍵過濾器

過濾出 rowkey 大於 10004 的資料:

// 過濾器
public static void scanFilterData(String tableName) throws IOException {
    Table table = connection.getTable(TableName.valueOf(tableName));

    // GREATER 大於、 BinaryComparator 按位元組索引順序比較指定位元組陣列
    Filter rowFilter = new RowFilter(CompareFilter.CompareOp.GREATER, new BinaryComparator(Bytes.toBytes("10004")));
    Scan scan = new Scan();
    scan.setFilter(rowFilter);

    ResultScanner resultScanner = table.getScanner(scan);
    for (Result result: resultScanner) {
        Cell[] cells = result.rawCells();
        for (Cell cell: cells) {
            System.out.println("行鍵: " + Bytes.toString(result.getRow()));
            System.out.println("列族: " + Bytes.toString(CellUtil.cloneFamily(cell)));
            System.out.println("列: " + Bytes.toString(CellUtil.cloneQualifier(cell)));
            System.out.println("值: " + Bytes.toString(CellUtil.cloneValue(cell)));

        }
    }
    table.close();
}

測試:

// t2 表中所有資料
hbase(main):008:0> scan 't2'
ROW                                COLUMN+CELL                                                                                       
10004                             column=info:alias2, timestamp=1628383262854, value=jun2                                           
10011                             column=info:alias4, timestamp=1628383262854, value=jun4                                           
10016                             column=info:alias5, timestamp=1628383262854, value=jun5                                           
3 row(s) in 0.1140 seconds

// 過濾器
scanFilterData("t2");

行鍵: 10011
列族: info
列: alias4
值: jun4

行鍵: 10016
列族: info
列: alias5
值: jun5

2.2 列族過濾器

過濾 info 列族:

 // 列族過濾器
public static void scanFilterCf(String tableName, String cf) throws IOException {
    Table table = connection.getTable(TableName.valueOf(tableName));

    // 獲取列族為 info 的記錄
    Filter cfFilter = new FamilyFilter(CompareFilter.CompareOp.EQUAL, new BinaryComparator(Bytes.toBytes(cf)));
    Scan scan = new Scan();
    scan.setFilter(cfFilter);

    ResultScanner resultScanner = table.getScanner(scan);
    for (Result result : resultScanner) {
        Cell[] cells = result.rawCells();
        for (Cell cell : cells) {
            System.out.println("行鍵: " + Bytes.toString(result.getRow()) +
                    "\t列族: " + Bytes.toString(CellUtil.cloneFamily(cell)) +
                    "\t列: " + Bytes.toString(CellUtil.cloneQualifier(cell)) +
                    "\t值: " + Bytes.toString(CellUtil.cloneValue(cell))
            );
        }
    }
    table.close();
}

測試:

scanFilterCf("t2", "info");
行鍵: 10004	列族: info	列: alias2	值: jun2
行鍵: 10011	列族: info	列: alias4	值: jun4
行鍵: 10016	列族: info	列: alias5	值: jun5

// 不存在的列族
scanFilterCf("t2", "info2");

2.3 列過濾器

// 獲取列為 alias2 的記錄
Filter qualifierFilter = new QualifierFilter(CompareFilter.CompareOp.EQUAL, new BinaryComparator(Bytes.toBytes(cn)));
Scan scan = new Scan();
scan.setFilter(qualifierFilter);

測試:

scanFilterCn("t2", "alias2");

行鍵: 10004	列族: info	列: alias2	值: jun2

2.4 值過濾器

// 獲取值為 jun5 的記錄
Filter valueFilter = new ValueFilter(CompareFilter.CompareOp.EQUAL, new BinaryComparator(Bytes.toBytes(value)));
Scan scan = new Scan();
scan.setFilter(valueFilter);

測試:

scanFilterValue("t2", "jun5");

行鍵: 10016	列族: info	列: alias5	值: jun5

2.5 時間戳過濾器

public static void scanFilterTimestamp(String tableName, long Timestamp) throws IOException {
    Table table = connection.getTable(TableName.valueOf(tableName));

    List<Long> list = new ArrayList<>();
    list.add(Timestamp);

    // 獲取時間戳為 1628383262854 的記錄
    TimestampsFilter timestampsFilter  = new TimestampsFilter(list);
    Scan scan = new Scan();
    scan.setFilter(timestampsFilter);

    ResultScanner resultScanner = table.getScanner(scan);
    for (Result result : resultScanner) {
        Cell[] cells = result.rawCells();
        for (Cell cell : cells) {
            System.out.println("行鍵: " + Bytes.toString(result.getRow()) +
                    "\t列族: " + Bytes.toString(CellUtil.cloneFamily(cell)) +
                    "\t列: " + Bytes.toString(CellUtil.cloneQualifier(cell)) +
                    "\t值: " + Bytes.toString(CellUtil.cloneValue(cell)) +
                    "\t時間戳: " + cell.getTimestamp()
            );
        }
    }
    table.close();
}

測試:

scanFilterTimestamp("t2", 1628383262854L);

行鍵: 10004	列族: info	列: alias2	值: jun2	時間戳: 1628383262854
行鍵: 10011	列族: info	列: alias4	值: jun4	時間戳: 1628383262854
行鍵: 10016	列族: info	列: alias5	值: jun5	時間戳: 1628383262854

3. 專用過濾器

3.1 單列值過濾器

public static void scanFilterSingleValue(String tableName, String cf, String cn, String value) throws IOException {
    Table table = connection.getTable(TableName.valueOf(tableName));

    SingleColumnValueFilter singleColumnValueFilter = new SingleColumnValueFilter(
            Bytes.toBytes(cf),
            Bytes.toBytes(cn),,
            CompareFilter.CompareOp.EQUAL,
            new SubstringComparator(value)
    );
    //如果不設定為 true,則那些不包含指定 column 的行也會返回
    singleColumnValueFilter.setFilterIfMissing(true);

    Scan scan = new Scan();
    scan.setFilter(singleColumnValueFilter);

    ResultScanner resultScanner = table.getScanner(scan);
    for (Result result : resultScanner) {
        Cell[] cells = result.rawCells();
        for (Cell cell : cells) {
            System.out.println("行鍵: " + Bytes.toString(result.getRow()) +
                    "\t列族: " + Bytes.toString(CellUtil.cloneFamily(cell)) +
                    "\t列: " + Bytes.toString(CellUtil.cloneQualifier(cell)) +
                    "\t值: " + Bytes.toString(CellUtil.cloneValue(cell)) +
                    "\t時間戳: " + cell.getTimestamp()
            );
        }
    }
    table.close();
}

測試:

scanFilterSingleValue("t2", "info", "alias2", "jun2");

行鍵: 10004	列族: info	列: alias2	值: jun2	時間戳: 1628383262854

// 註釋  singleColumnValueFilter.setFilterIfMissing(true);
行鍵: 10004	列族: info	列: alias2	值: jun2	時間戳: 1628383262854
行鍵: 10011	列族: info	列: alias4	值: jun4	時間戳: 1628383262854
行鍵: 10016	列族: info	列: alias5	值: jun5	時間戳: 1628383262854

3.2 單列值排除器

public static void scanFilterSingleExcludeValue(String tableName, String cf, String cn, String value) throws IOException {
    Table table = connection.getTable(TableName.valueOf(tableName));

    SingleColumnValueExcludeFilter singleColumnValueExcludeFilter = new SingleColumnValueExcludeFilter(
            Bytes.toBytes(cf),
            Bytes.toBytes(cn),
            CompareFilter.CompareOp.EQUAL,
            Bytes.toBytes(value)

//                new SubstringComparator(value)
    );
    //如果不設定為 true,則那些不包含指定 column 的行也會返回
    singleColumnValueExcludeFilter.setFilterIfMissing(true);

    Scan scan = new Scan();
    scan.setFilter(singleColumnValueExcludeFilter);

    ResultScanner resultScanner = table.getScanner(scan);
    for (Result result : resultScanner) {
        Cell[] cells = result.rawCells();
        for (Cell cell : cells) {
            System.out.println("行鍵: " + Bytes.toString(result.getRow()) +
                    "\t列族: " + Bytes.toString(CellUtil.cloneFamily(cell)) +
                    "\t列: " + Bytes.toString(CellUtil.cloneQualifier(cell)) +
                    "\t值: " + Bytes.toString(CellUtil.cloneValue(cell)) +
                    "\t時間戳: " + cell.getTimestamp()
            );
        }
    }
    table.close();
}

測試:

scanFilterSingleExcludeValue("t2", "info", "alias2", "jun2");

3.3 字首過濾器(針對行鍵)

public static void scanFilterPrefix(String tableName, String rowKeyPrefix) throws IOException {
    Table table = connection.getTable(TableName.valueOf(tableName));

    PrefixFilter prefixFilter = new PrefixFilter(Bytes.toBytes(rowKeyPrefix));
    Scan scan = new Scan();
    scan.setFilter(prefixFilter);

    ResultScanner resultScanner = table.getScanner(scan);
    for (Result result : resultScanner) {
        Cell[] cells = result.rawCells();
        for (Cell cell : cells) {
            System.out.println("行鍵: " + Bytes.toString(result.getRow()) +
                    "\t列族: " + Bytes.toString(CellUtil.cloneFamily(cell)) +
                    "\t列: " + Bytes.toString(CellUtil.cloneQualifier(cell)) +
                    "\t值: " + Bytes.toString(CellUtil.cloneValue(cell)) +
                    "\t時間戳: " + cell.getTimestamp()
            );
        }
    }
    table.close();
}

測試:

scanFilterPrefix("t2", "1001");

行鍵: 10011	列族: info	列: alias4	值: jun4	時間戳: 1628383262854
行鍵: 10016	列族: info	列: alias5	值: jun5	時間戳: 1628383262854

3.4 列字首過濾器

public static void scanFilterColumnPrefix(String tableName, String CnPrefix) throws IOException {
    Table table = connection.getTable(TableName.valueOf(tableName));

    ColumnPrefixFilter columnPrefixFilter = new ColumnPrefixFilter(Bytes.toBytes(CnPrefix));
    Scan scan = new Scan();
    scan.setFilter(columnPrefixFilter);

    ResultScanner resultScanner = table.getScanner(scan);
    for (Result result : resultScanner) {
        Cell[] cells = result.rawCells();
        for (Cell cell : cells) {
            System.out.println("行鍵: " + Bytes.toString(result.getRow()) +
                    "\t列族: " + Bytes.toString(CellUtil.cloneFamily(cell)) +
                    "\t列: " + Bytes.toString(CellUtil.cloneQualifier(cell)) +
                    "\t值: " + Bytes.toString(CellUtil.cloneValue(cell)) +
                    "\t時間戳: " + cell.getTimestamp()
            );
        }
    }
    table.close();
}

測試:

scanFilterColumnPrefix("t2", "ali");

行鍵: 10004	列族: info	列: alias2	值: jun2	時間戳: 1628383262854
行鍵: 10011	列族: info	列: alias4	值: jun4	時間戳: 1628383262854
行鍵: 10016	列族: info	列: alias5	值: jun5	時間戳: 1628383262854

3.5 分頁過濾器

public static void scanFilterPage(String tableName, int pageNum) throws IOException {
    Table table = connection.getTable(TableName.valueOf(tableName));

    PageFilter pageFilter = new PageFilter(pageNum);
    Scan scan = new Scan();
    scan.setFilter(pageFilter);

    ResultScanner resultScanner = table.getScanner(scan);

//        // 獲取最後一行的 rowkey,為lastRowkey加上了一個0位元組(byte陣列初始化
//        //後預設填入的就是0位元組),不希望第二次的Scan結果集把第一次的最後一條記錄包含進去
//        byte[] lastRowKey = getLastRowKey(resultScanner);
//        System.out.println("lastRowKey: " + Bytes.toString(lastRowKey));
//
//        // 獲取第 2 頁
//        byte[] startRowKey = Bytes.add(lastRowKey, new byte[1]);
//        scan.setStartRow(startRowKey);
//        ResultScanner rs2 = table.getScanner(scan);
//
//        getLastRowKey(rs2);

    // 迴圈獲取所有資料
    while (true) {
        byte[] lastRowKey = getLastRowKey(resultScanner);
        if (lastRowKey == null) {
            break;
        }

        // 獲取下一頁
        byte[] startRowKey = Bytes.add(lastRowKey, new byte[1]);
        scan.setStartRow(startRowKey);
        resultScanner = table.getScanner(scan);
    }
    table.close();
}

// 獲取最後記錄的 rowKey
private static byte[] getLastRowKey(ResultScanner rs) {
    byte[] lastRowKey = null;
    for (Result r : rs) {
        byte[] rowkey = r.getRow();
        lastRowKey = rowkey;
        System.out.println("rowkey: " + Bytes.toString(rowkey));
    }
    return lastRowKey;
}

測試:

// 設定分頁數量為 2,總共有 3 行
scanFilterPage("t2", 2);

rowkey: 10004
rowkey: 10011
rowkey: 10016

注意:PageFilte 不能實現翻頁,如果想翻頁就得記錄上一次翻頁的最後一個 rowkey