hbase過濾器

引言 -- 參數基礎html

1. 結構(Structural)過濾器--FilterList正則表達式

2.列值過濾器--SingleColumnValueFilterapache

          2.1.第一種構造函數狀況 -- 比較的關鍵字是字符數組api

          2.2.第二種構造函數狀況 -- 比較的關鍵字是比較器ByteArrayComparable數組

3.鍵值元數據ide

          3.1. 基於列族過濾數據的FamilyFilter函數

          3.2. 基於限定符Qualifier(列)過濾數據的QualifierFilteroop

          3.3. 基於列名(即Qualifier)前綴過濾數據的ColumnPrefixFilter測試

          3.4. 基於多個列名(即Qualifier)前綴過濾數據的MultipleColumnPrefixFilterui

          3.5. 基於列範圍(不是行範圍)過濾數據ColumnRangeFilter

4. RowKey

5. Utility--FirstKeyOnlyFilter

6. 取得查詢結果

有兩個參數類在各種Filter中常常出現,統一介紹下:

(1)比較運算符  CompareFilter.CompareOp

比較運算符用於定義比較關係, 能夠有如下幾類值供選擇:

EQUAL                                  相等
GREATER                              大於
GREATER_OR_EQUAL           大於等於
LESS                                      小於
LESS_OR_EQUAL                  小於等於
NOT_EQUAL                        不等於
(2)比較器   ByteArrayComparable

經過比較器能夠實現多樣化目標匹配效果,比較器 有如下子類能夠使用:

BinaryComparator                   匹配完整字節數組 
BinaryPrefixComparator     匹配字節數組前綴 
BitComparator
NullComparator
RegexStringComparator    正則表達式匹配
SubstringComparator        子串匹配
1. 結構(Structural)過濾器-- FilterList

FilterList  表明一個 過濾器鏈 ,它能夠包含一組即將應用於目標數據集的過濾器 ,過濾器間具備「與」   FilterList.Operator.MUST_PASS_ ALL   和「或」   FilterList.Operator.MUST_PASS_ ONE   關係。

官網實例代碼, 兩個 「 或」 關係的 過濾器 的寫法:

FilterList list = new FilterList(FilterList.Operator.MUST_PASS_ONE);   //數據只要知足一組過濾器中的一個就能夠

SingleColumnValueFilter filter1 = new SingleColumnValueFilter(

column,

CompareOp.EQUAL,

Bytes.toBytes("my value")

list.add(filter1);

SingleColumnValueFilter filter2 = new SingleColumnValueFilter(

column,

CompareOp.EQUAL,

Bytes.toBytes("my other value")

list.add(filter2);

Scan scan = new Scan();

scan.setFilter(list);

2. 列值過濾器-- SingleColumnValueFilter

SingleColumnValueFilter  用於測試 列值 相等 (CompareOp.EQUAL ), 不等 (CompareOp.NOT_EQUAL),或單側範圍 (e.g., CompareOp.GREATER) 。

構造函數:

(1)比較的關鍵字是一個 字符數組

SingleColumnValueFilter(byte[] family, byte[] qualifier, CompareFilter.CompareOp compareOp, byte[] value)

(2)比較的關鍵字是一個 比較器 (比較器下一小節作介紹)

SingleColumnValueFilter(byte[] family, byte[] qualifier, CompareFilter.CompareOp compareOp,

ByteArrayComparable comparator

)
2.1.第一種構造函數狀況 -- 比較的關鍵字是字符數組

官網示例代碼 , 檢查列值和字符串'my value' 相等:

SingleColumnValueFilter filter = new SingleColumnValueFilter(

column,

CompareOp.EQUAL,

Bytes.toBytes("my value")

scan.setFilter(filter);

我的實測代碼:

        HTable table = HBaseDAO. getHTable ( "147patents" );

        FilterList filterList =  new  FilterList(FilterList.Operator. MUST_PASS_ALL );

 
        SingleColumnValueFilter filter =  new  SingleColumnValueFilter(

                Bytes. toBytes ( "patentinfo" ),

                Bytes. toBytes ( "CREATE_TIME" ),

                CompareOp. EQUAL ,

                Bytes. toBytes ( " 2013-06-08 " )

                );

        filterList.addFilter(filter);

        Scan scan =  new  Scan();

        scan.setFilter(filterList);

        ResultScanner rs = table.getScanner(scan);

         for  (Result r : rs) {

            System. out .println( "Scan: "  + r);

        }

        table.close();

 
注意: 仍是大寫問題,HBase的列名必須大寫!

2.2.第二種構造函數狀況 -- 比較的關鍵字是比較器 ByteArrayComparable

該章節主要是針對 SingleColumnValueFilter的 第二種構造函數使用狀況作了一些舉例:

(1) 支持值比較的 正則表達式  --  RegexStringComparator

官網示例代碼 :

RegexStringComparator comp  = new  RegexStringComparator ("my.");   //任意以my打頭的值

SingleColumnValueFilter filter = new SingleColumnValueFilter(

column,

CompareOp.EQUAL,

comp

scan.setFilter(filter);

我的實測代碼:

        HTable table = HBaseDAO. getHTable ( "147patents" );

        FilterList filterList =  new  FilterList(FilterList.Operator. MUST_PASS_ALL );

       

         RegexStringComparator comp =  new  RegexStringComparator( "2013-06-1." );

       

        SingleColumnValueFilter filter =  new  SingleColumnValueFilter(

                Bytes. toBytes ( "patentinfo" ),

                Bytes. toBytes ( "CREATE_TIME" ),

                CompareOp. EQUAL ,

                 comp

                );

        filterList.addFilter(filter);

        Scan scan =  new  Scan();

        scan.setFilter(filterList);

        ResultScanner rs = table.getScanner(scan);

         for  (Result r : rs) {

            System. out .println( "Scan: "  + r);

        }

        table.close();

 
(2) 檢測一個子串是否存在於值中( 大小寫不敏感 ) -- SubstringComparator

官網示例代碼:

SubstringComparator comp = new SubstringComparator ("y val");   // looking for 'my value'

SingleColumnValueFilter filter = new SingleColumnValueFilter(

column,

CompareOp.EQUAL,

scan.setFilter(filter);

我的實測代碼:

        HTable table = HBaseDAO. getHTable ( "147patents" );

        FilterList filterList =  new  FilterList(FilterList.Operator. MUST_PASS_ALL );

       

//        RegexStringComparator  comp  = new RegexStringComparator("2013-06-1.");

         SubstringComparator comp =  new  SubstringComparator( "2013-06-1" );

       

        SingleColumnValueFilter filter =  new  SingleColumnValueFilter(

                Bytes. toBytes ( "patentinfo" ),

                Bytes. toBytes ( "CREATE_TIME" ),

                CompareOp. EQUAL ,

                comp

                );

        filterList.addFilter(filter);

        Scan scan =  new  Scan();

        scan.setFilter(filterList);

        ResultScanner rs = table.getScanner(scan);

         for  (Result r : rs) {

            System. out .println( "Scan: "  + r);

        }

        table.close();

 

(3)BinaryComparator

二進制比較器,用得較少,有須要請自行查閱官網:http://hbase.apache.org/apidocs/org/apache/hadoop/hbase/filter/BinaryComparator.html

(4)BinaryPrefixComparator

二進制前綴比較器 ,用得較少 ,有須要請自行查閱官網: http://hbase.apache.org/apidocs/org/apache/hadoop/hbase/filter/BinaryPrefixComparator.html

3. 鍵值元數據
因爲HBase 採用 鍵值對 保存內部數據, 鍵值 元數據 過濾器 評估一行的 鍵 (ColumnFamily:Qualifiers) 是否存在  , 對應前節所述值的狀況。

3.1. 基於 列族 過濾數據的 FamilyFilter

構造函數:

FamilyFilter(CompareFilter.CompareOp familyCompareOp, ByteArrayComparable familyComparator)

我的實測代碼:

        HTable table = HBaseDAO. getHTable ( "147patents" );

         /**

         * FamilyFilter構造函數中第二個參數是ByteArrayComparable類型

         * ByteArrayComparable類參見「引言-參數基礎」章節

         * 下面僅以最可能用到的BinaryComparator、BinaryPrefixComparator舉例:

         */

        FamilyFilter  ff  =  new  FamilyFilter(

                CompareFilter.CompareOp. EQUAL  ,

                 new  BinaryComparator(Bytes. toBytes ( "pat" ))    //表中不存在pat列族,過濾結果爲空

                );

        FamilyFilter ff1 =  new  FamilyFilter(

                CompareFilter.CompareOp. EQUAL  ,

                 new  BinaryPrefixComparator(Bytes. toBytes ( "pat" ))    //表中存在以pat打頭的列族 patentinfo ,過濾結果爲該列族全部行

                );

        Scan scan =  new  Scan();

        scan.setFilter(ff1);

        ResultScanner rs = table.getScanner(scan);

 

注意:

若是但願查找的是一個已知的列族,則使用  scan.addFamily( family)    比使用過濾器效率更高;
因爲目前HBase對多列族支持不完善,因此該過濾器目前用途不大。
3.2.  基於限定符Qualifier(列)過濾數據 的 QualifierFilter

構造函數:

QualifierFilter(CompareFilter.CompareOp op, ByteArrayComparable qualifierComparator)

我的實測代碼:

        HTable table = HBaseDAO. getHTable ( "147patents" );

         /**

         * QualifierFilter構造函數中第二個參數是ByteArrayComparable類型

         * ByteArrayComparable類有如下子類能夠使用:

         * *******************************************

         * BinaryComparator  匹配完整字節數組,

         * BinaryPrefixComparator  匹配開始的部分字節數組,

         * BitComparator,

         * NullComparator,

         * RegexStringComparator,   正則表達式匹配

         * SubstringComparator

         * *******************************************

         * 下面僅以最可能用到的BinaryComparator、BinaryPrefixComparator舉例:

         */

        QualifierFilter  ff  =  new  QualifierFilter(

                CompareFilter.CompareOp. EQUAL  ,

                 new  BinaryComparator(Bytes. toBytes ( "belong" ))    //表中不存在belong列,過濾結果爲空

                );

        QualifierFilter ff1 =  new  QualifierFilter(

                CompareFilter.CompareOp. EQUAL  ,

                 new  BinaryPrefixComparator(Bytes. toBytes ( "BELONG" ))    //表中存在以BELONG打頭的列BELONG_SITE,過濾結果爲全部行的該列數據

                );

        Scan scan =  new  Scan();

        scan.setFilter(ff1);

        ResultScanner rs = table.getScanner(scan);

 
說明:

一旦涉及到列(Qualifier),HBase就只認大寫字母了!
該過濾器應該比 FamilyFilter更經常使用!
3.3.  基於 列名(即Qualifier) 前綴 過濾數據的 ColumnPrefixFilter   ( 該功能用 QualifierFilter也能實現 )

構造函數:

ColumnPrefixFilter(byte[] prefix)

注意:

一個列名是能夠出如今多個列族中的,該過濾器將返回全部列族中匹配的列。

官網示例代碼,查找全部"abc "打頭的列:

HTableInterface t = ...;

byte[] row = ...;

byte[] family = ...;

byte[] prefix = Bytes.toBytes("abc");

Scan scan = new Scan(row, row); // (optional) limit to one row

scan.addFamily(family); // (optional) limit to one family

Filter f = new ColumnPrefixFilter(prefix);

scan.setFilter(f);

scan.setBatch(10); // set this if there could be many columns returned

ResultScanner rs = t.getScanner(scan);

for (Result r = rs.next(); r != null; r = rs.next()) {

for (KeyValue kv : r.raw()) {

// each kv represents a column

}

}

rs.close();

我的實測代碼:

        HTable table = HBaseDAO. getHTable ( "147patents" );


         //返回全部行中以BELONG打頭的列的數據

 
        ColumnPrefixFilter ff1 =  new  ColumnPrefixFilter(Bytes. toBytes ( "BELONG" ));

        Scan scan =  new  Scan();

        scan.setFilter(ff1);

        ResultScanner rs = table.getScanner(scan);

 
3.4.  基於 多個 列名(即Qualifier) 前綴 過濾數據的 MultipleColumnPrefixFilter

說明:

MultipleColumnPrefixFilter 和 ColumnPrefixFilter 行爲差很少,但能夠指定 多個前綴 。

官方示例代碼,查找全部"abc"或"xyz"打頭的列:

HTableInterface t = ...;

byte[] row = ...;

byte[] family = ...;

byte[][] prefixes = new byte[][] {Bytes.toBytes("abc"), Bytes.toBytes("xyz")};

Scan scan = new Scan(row, row); // (optional) limit to one row

scan.addFamily(family); // (optional) limit to one family

Filter f = new MultipleColumnPrefixFilter(prefixes);

scan.setFilter(f);

scan.setBatch(10); // set this if there could be many columns returned

ResultScanner rs = t.getScanner(scan);

for (Result r = rs.next(); r != null; r = rs.next()) {

for (KeyValue kv : r.raw()) {

// each kv represents a column

}

}

rs.close();

我的實測代碼:

        HTable table = HBaseDAO. getHTable ( "147patents" );

       

         byte [][] prefixes =  new   byte [][] {Bytes. toBytes ( "BELONG" ), Bytes. toBytes ( "CREATE" )};

         //返回全部行中以BELONG或者CREATE打頭的列的數據

        MultipleColumnPrefixFilter ff =  new  MultipleColumnPrefixFilter(prefixes);

        Scan scan =  new  Scan();

        scan.setFilter(ff);

        ResultScanner rs = table.getScanner(scan);

 
3.5.  基於 列範圍 (不是行範圍)過濾數據 ColumnRangeFilter

說明:

可用於得到一個範圍的列,例如,若是你的一行中有百萬個列,可是你只但願查看列名爲bbbb到dddd的範圍
該方法從 HBase 0.92 版本開始引入
一個列名是能夠出如今多個列族中的,該過濾器將返回全部列族中匹配的列

構造函數:

ColumnRangeFilter(byte[] minColumn, boolean minColumnInclusive, byte[] maxColumn, boolean maxColumnInclusive)

參數解釋:

minColumn - 列範圍的最小值,若是爲空,則沒有下限;
minColumnInclusive - 列範圍是否包含minColumn   ;
maxColumn - 列範圍最大值,若是爲空,則沒有上限;
maxColumnInclusive - 列範圍是否包含 maxColumn  。
官網示例代碼,查找列名在" bbbb"到"dddd"範圍的數據 :

HTableInterface t = ...;

byte[] row = ...;

byte[] family = ...;

byte[] startColumn = Bytes.toBytes("bbbb");

byte[] endColumn = Bytes.toBytes("bbdd");

Scan scan = new Scan(row, row); // (optional) limit to one row

scan.addFamily(family); // (optional) limit to one family

Filter f = new ColumnRangeFilter(startColumn, true, endColumn, true);

scan.setFilter(f);

scan.setBatch(10); // set this if there could be many columns returned

ResultScanner rs = t.getScanner(scan);

for (Result r = rs.next(); r != null; r = rs.next()) {

for (KeyValue kv : r.raw()) {

// each kv represents a column

}

}

rs.close();

我的實測代碼:

        HTable table = HBaseDAO. getHTable ( "147patents" );

       

         byte [] startColumn = Bytes. toBytes ( "C" );

         byte [] endColumn = Bytes. toBytes ( "D" );

         //返回全部列中從C到D打頭的範圍的數據,實際返回相似CREATOR、CREATE_TIME、CHANNEL_CODE等列的數據

        ColumnRangeFilter ff =  new  ColumnRangeFilter(startColumn,  true , endColumn,  true );

       

        Scan scan =  new  Scan();

        scan.setFilter(ff);

        ResultScanner rs = table.getScanner(scan);

 
4. RowKey

當須要 根據行鍵特徵 查找一個範圍的行數據時,使用 Scan的 startRow和stopRow 會更高效,可是, startRow和stopRow 只能匹配行鍵的開始字符 ,而不能匹配中間包含的字符 :

         byte [] startColumn = Bytes. toBytes ( "aaa" );

         byte [] endColumn = Bytes. toBytes ( "bbb" );

        Scan scan =  new  Scan(startColumn,endColumn);

當須要針對行鍵進行更復雜的過濾時,能夠使用 RowFilter:

構造函數:

RowFilter(CompareFilter.CompareOp rowCompareOp, ByteArrayComparable rowComparator)

參數解釋 參見「引言-參數基礎」章節。

我的實測代碼:

        HTable table = HBaseDAO. getHTable ( "147patents" );

         /**

         *  rowkey 格式爲: 建立日期_ 發佈日期 _ID_TITLE

         *  目標:查找   發佈日期   在  2013 - 07 - 10  到  2013 - 07 - 11  之間的數據

         */

        RowFilter rf =  new  RowFilter(

                CompareFilter.CompareOp. EQUAL  ,

                 new  SubstringComparator( "_2013-07-16_" )  

                );

        Scan scan =  new  Scan();

        scan.setFilter(rf);

        ResultScanner rs = table.getScanner(scan);

 
注意:
測試過程當中嘗試經過組合使用兩個RowFilter( CompareFilter.CompareOp參數分別爲 GREATER_OR_EQUAL 和 LESS_OR_EQUAL ),和 SubstringComparator, 過濾找出指定發佈時間範圍內的數據,但結果比較意外,不是預想的數據,估計比較運算符 GREATER_OR_EQUAL 和 LESS_OR_EQUAL 和比較器 SubstringComparator組合使用效果不太好,慎用。

5. Utility- - FirstKeyOnlyFilter

該過濾器僅僅返回每一行中的第一個cell的值, 能夠用於高效的執行行數統計操做。

估計實戰意義不大。

構造函數:

public FirstKeyOnlyFilter()

我的實測代碼:

        HTable table = HBaseDAO. getHTable ( "147patents" );

        FirstKeyOnlyFilter fkof =  new  FirstKeyOnlyFilter();

        Scan scan =  new  Scan();

        scan.setFilter(fkof);

        ResultScanner rs = table.getScanner(scan);

 
6. 取得查詢結果

不管是官網的 Ref Guide仍是網上流傳的大部分博客中,輸出查詢結果的代碼都是:

for (Result r = rs.next(); r != null; r = rs.next()) {

for (KeyValue kv : r.raw()) {

// each kv represents a column

}

}

但查看最新的API可知Result實例的raw()方法已經不建議使用了:

raw()  Deprecated.  as of 0.96, use rawCells()

0.96之後版本正確的獲取結果代碼以下:

         for  (Result r : rs) {

             for  (Cell cell : r.rawCells()) {

                System. out .println(

                         "Rowkey : " +Bytes. toString ( r.getRow() )+

                         "Familiy:Quilifier : " +Bytes. toString ( CellUtil. cloneQualifier (cell))+

                         "Value : " +Bytes. toString ( CellUtil. cloneValue (cell))

                        );

            }

        }

相關文章
相關標籤/搜索