HBase Filter 過(guò)濾器

HBase 的基本 API,包括增、刪、改、查等。查詢可以根據(jù) Rowkey 進(jìn)行 Get 或根據(jù) Rowkey 的范圍進(jìn)行 Scan 掃描。同時(shí)提供了更加高級(jí)的過(guò)濾器(Filter)在 Server 端過(guò)濾查詢結(jié)果,只將滿足條件的數(shù)據(jù)返回給客戶端。

過(guò)濾器的類型很多,可以分為兩大類:比較過(guò)濾器和專用過(guò)濾器。

比較運(yùn)算符和比較器

比較過(guò)濾器需要兩個(gè)參數(shù):比較運(yùn)算符和比較器

比較運(yùn)算符

在比較過(guò)濾器中需要用到比較運(yùn)算符,HBase 內(nèi)置以下7種比較運(yùn)算符

public enum CompareOp {       
    LESS,  // 檢查是否小于比較器里的值       
    LESS_OR_EQUAL,  // 檢查是否小于或等于比較器里的值       
    EQUAL,  // 檢查是否等于比較器里的值       
    NOT_EQUAL, // 檢查是否不等于比較器里的值   
    GREATER_OR_EQUAL,  // 檢查是否大于或等于比較器里的值   
    GREATER,  // 檢查是否大于比較器里的值       
    NO_OP,  // 默認(rèn)返回false,因此過(guò)濾掉所有的數(shù)據(jù)     
}  

比較器

通過(guò)比較器可以實(shí)現(xiàn)多樣化目標(biāo)匹配效果,比較器有以下子類可以使用:

BinaryComparator          // 匹配完整字節(jié)數(shù)組  
BinaryPrefixComparator    // 匹配字節(jié)數(shù)組前綴 
BitComparator // 按位執(zhí)行與、或、異或比較 
NullComparator // 判斷當(dāng)前值是不是 NULL 
RegexStringComparator     // 正則表達(dá)式匹配字符串 
SubstringComparator       // 子串匹配,相當(dāng)于 contains()

比較過(guò)濾器

行鍵過(guò)濾器 RowFilter

Scan scan = new Scan(); 

Filter filter = new RowFilter(CompareOp.LESS_OR_EQUAL, 
    new BinaryComparator(Bytes.toBytes("uid-100"))); 
scan.setFilter(filter);

篩選出匹配的所有的行,基于行鍵(Rowkey)過(guò)濾數(shù)據(jù),可以執(zhí)行精確匹配,子字符串匹配或正則表達(dá)式匹配,過(guò)濾掉不匹配的數(shù)據(jù)。

一般來(lái)說(shuō),對(duì) Rowkey 進(jìn)行范圍過(guò)濾,可以執(zhí)行 Scan 的 startKey 和 endKey,RowFilter 可以更精確的過(guò)濾。

列族過(guò)濾器 FamilyFilter

Scan scan = new Scan(); 

Filter filter = new FamilyFilter(CompareFilter.CompareOp.LESS, 
      new BinaryComparator(Bytes.toBytes("cf-d"))); 
scan.setFilter(filter);

與 RowFilter 類似,區(qū)別是比較列族,而不是比較行鍵。當(dāng) HBase 表有多個(gè)列族時(shí),可以用來(lái)篩選不同列族中的列。

列名過(guò)濾器 QualifierFilter

Scan scan = new Scan(); 

Filter filter = new QualifierFilter(CompareFilter.CompareOp.EQUAL, 
    new BinaryComparator(Bytes.toBytes("col-1"))); 
scan.setFilter(filter1);

根據(jù)列名進(jìn)行篩選。

值過(guò)濾器 ValueFilter

Scan scan = new Scan(); 

Filter filter = new ValueFilter(CompareFilter.CompareOp.NOT_EQUAL, 
    new SubstringComparator("abc")); 
scan.setFilter(filter);

篩選特定值的單元格,可以與 RegexStringComparator 搭配使用,完成復(fù)雜的篩選。

不同的比較器,只能與部分比較運(yùn)算符搭配,例如 SubstringComparator 只能使用 EQUALNOT_EQUAL

參考列過(guò)濾器 DependentColumnFilter

Scan scan = new Scan(); 

Filter filter = new DependentColumnFilter(Bytes.toBytes("cf-d"), 
    Bytes.toBytes("col-1"), 
    "false", 
    CompareOp.EQUAL, 
    new BinaryComparator(Bytes.toBytes("val-1")))) 
scan.setFilter(filter);

一種更復(fù)雜的過(guò)濾器,不止簡(jiǎn)單的通過(guò)用戶指定的信息篩選數(shù)據(jù)。允許指定一個(gè)參考列或引用列,使用參考列控制其他列的過(guò)濾。該過(guò)濾器會(huì)使用參考列的時(shí)間戳,并在過(guò)濾時(shí)包括所有與引用時(shí)間戳相同的列。

參考列過(guò)濾器相當(dāng)于一個(gè) ValueFilter 和一個(gè)時(shí)間戳過(guò)濾器的組合。

專用過(guò)濾器

單列值過(guò)濾器 SingleColumnValueFilter

使用某一列的值,決定一行數(shù)據(jù)是否被過(guò)濾。

Scan scan = new Scan(); 

SingleColumnValueFilter filter = new SingleColumnValueFilter(Bytes.toBytes("cf-d"), 
    Bytes.toBytes("col-5"), 
    CompareFilter.CompareOp.NOT_EQUAL, 
    new SubstringComparator("val-1")); 
filter.setFilterIfMissing(true); // 如果不設(shè)置為 true,那些不包含指定列的行也會(huì)返回 
scan.setFilter(filter);

對(duì)于不包含指定列的行數(shù)據(jù),通過(guò) setFilterIfMissing() 決定是否返回。

單列值排除器 SingleColumnValueExcludeFilter

繼承自 SingleColumnValueFilter,實(shí)現(xiàn)的與單列值過(guò)濾器相反的語(yǔ)義。

行前綴過(guò)濾器 PrefixFilter

Scan scan = new Scan(); 

Filter filter = new PrefixFilter(Bytes.toBytes("row1")); 
scan.setFilter(filter);

基于行鍵(Rowkey)的前綴過(guò)濾行數(shù)據(jù)。Scan 操作以字典序查找,當(dāng)行鍵大于前綴時(shí),Scan 結(jié)束。

列前綴過(guò)濾器 ColumnPrefixFilter

Scan scan = new Scan(); 

Filter filter = new ColumnPrefixFilter(Bytes.toBytes("col-")); 
scan.setFilter(filter);

通過(guò)對(duì)列名稱的前綴匹配過(guò)濾,返回的結(jié)果只包含滿足過(guò)濾器的列。

分頁(yè)過(guò)濾器 PageFilter

byte[] lastRow = null; 
Filter filter = new PageFilter(10); 

while(true) { 
    int rowCount = 0; 
    Scan scan = new Scan(); 
    scan.setFilter(filter); 
    scan.setStartRow(lastRow); 

    ResultScanner resultScanner = table.getScanner(scan); 
    Iterator<Result> resultIterator = resultScanner.iterator(); 
    while (resultIterator.hasNext()) { 
        Result result = resultIterator.next(); 
        // ... 
        lastRow = result.getRow(); // 記錄最后一行的rowkey 
        rowCount++; // 記錄本頁(yè)行數(shù) 
    } 

    if(rowCount <= 10) { 
        break; 
    } 
}

使用該過(guò)濾器,對(duì)結(jié)果進(jìn)行按行分野,需要指定 pageSize 參數(shù),控制每頁(yè)返回的行數(shù),并設(shè)置 startRow 多次調(diào)用 getScanner(),感覺(jué)功能只適用于一些特殊場(chǎng)景,性能也并不高。

行鍵過(guò)濾器 KeyOnlyFilter

KeyOnlyFilter filter = new KeyOnlyFilter(); 
KeyOnlyFilter filter = new KeyOnlyFilter(true);

這個(gè) Filter 只會(huì)返回每行的行鍵+列簇+列,而不返回值(value),對(duì)不需要值的應(yīng)用場(chǎng)景來(lái)說(shuō),非常實(shí)用,減少了值的傳遞。構(gòu)造方法可以設(shè)置 lenAsValue 參數(shù)(默認(rèn) false),表示返回時(shí),value 設(shè)為原列值的長(zhǎng)度。

首次行鍵過(guò)濾器 FirstKeyOnlyFilter

FirstKeyOnlyFilter filter = new FirstKeyOnlyFilter();

這個(gè) Filter 僅僅返回每一行中的第一個(gè) cell 的值,可以用于高效的執(zhí)行行數(shù)統(tǒng)計(jì)操作,在掃描到第一個(gè) cell 時(shí),立即跳到下一行數(shù)據(jù),性能相比全表掃描得到提升。

包含結(jié)束的過(guò)濾器 InclusiveStopFilter

Filter filter = new InclusiveStopFilter(Bytes.toBytes("uid-10"));

一般的掃描結(jié)果中,設(shè)置一個(gè)開(kāi)始行鍵和一個(gè)終止行鍵,是前閉后開(kāi)區(qū)間,不包含結(jié)束行,使用這個(gè)過(guò)濾器時(shí)將結(jié)束行加入到結(jié)果中。

時(shí)間戳過(guò)濾器 TimestampsFilter

Filter filter = new TimestampsFilter(Arrays.asList(5L, 10L, 15L)); 
Scan scan1 = new Scan(); 
scan1.setMaxVersions(3) 
scan1.setFilter(filter); 

Scan scan2 = new Scan(); 
scan2.setMaxVersions(3) 
scan2.setFilter(filter); 
scan2.setTimeRange(8, 12);

當(dāng)需要在掃描結(jié)果中對(duì)版本進(jìn)行細(xì)粒度控制時(shí),可以使用這個(gè) Filter 傳入一個(gè)時(shí)間戳集合,對(duì)時(shí)間進(jìn)行限制,只會(huì)返回與指定時(shí)間戳相同的版本數(shù)據(jù),并且與設(shè)置時(shí)間戳范圍共同使用。

列計(jì)數(shù)過(guò)濾器 ColumnCountGetFilter

Filter filter = new ColumnCountGetFilter(10);

使用這個(gè)過(guò)濾器,限制每行最多返回多少列。注意當(dāng)一行的列數(shù)達(dá)到設(shè)定的最大值,過(guò)濾器會(huì)停止 Scan 操作,所以不適合全表掃描,適合在 Get 方法中使用。

列分頁(yè)過(guò)濾器 ColumnPaginationFilter

Filter filter = new ColumnPaginationFilter(10,5);

與 PageFilter 類似,可以對(duì)一行的所有列進(jìn)行分也,需要傳入偏移量 offset 和返回?cái)?shù)量 limit。

隨機(jī)行過(guò)濾器 RandomRowFilter

Filter filter = new RandomRowFilter(0.5F);

這個(gè) Filter 可以使結(jié)果中包含隨機(jī)行,參數(shù) chance 取值在 0.0 到 1.0 之間,表示隨機(jī)取行數(shù)的比例,每一行會(huì)調(diào)用 Random.nextFloat() 與 chance 比較來(lái)確定是否被過(guò)濾。

附加過(guò)濾器

普通過(guò)濾器可以提供對(duì)返回結(jié)果的篩選限制,一些額外的控制可以附加在過(guò)濾器上

跳轉(zhuǎn)過(guò)濾器 SkipFilter

Scan scan = new Scan(); 
Filter filter1 = new ValueFilter(CompareFilter.CompareOp.NOT_EQUAL, 
    new BinaryComparator(Bytes.toBytes("val-0"))); 
Filter filter2 = new SkipFilter(filter1);

包裝了用戶的一個(gè)過(guò)濾器,當(dāng)過(guò)濾器發(fā)現(xiàn)某一行的一列需要過(guò)濾時(shí),整行數(shù)據(jù)都被過(guò)濾掉。上面的例子是,使用 SkipFilter 和 ValueFilter 組合,獲取不等于指定列值的行,同時(shí)過(guò)濾掉其他不符合條件的行(即只要有一行中一列的值等于“val-0”,就會(huì)被過(guò)濾)。

全匹配過(guò)濾 WhileMatchFilter

Scan scan = new Scan(); 
Filter filter1 = new ValueFilter(CompareFilter.CompareOp.NOT_EQUAL, 
    new BinaryComparator(Bytes.toBytes("val-0"))); 
Filter filter2 = new WhileMatchFilter(filter1);

與SkipFilter 相似,不過(guò)當(dāng)一條數(shù)據(jù)被過(guò)濾掉時(shí),會(huì)停止 Scan 操作。可以用來(lái)檢查全表數(shù)據(jù)中,是否有某些數(shù)據(jù)不符合條件。

多種過(guò)濾條件的使用方法

通過(guò) FilterList 實(shí)例可以提供多個(gè)過(guò)濾器共同使用的功能。并且可以指定對(duì)多個(gè)過(guò)濾器的過(guò)濾結(jié)果如何組合。

FilterList 構(gòu)造函數(shù)和方法

FilterList(List<Filter> rowFilters) 
FilterList(Operator operator) 
FilterList(Operator operator, List<Filter> rowFilters) 

void addFilter(Filter filter)

FilterList.Operator 決定了過(guò)濾器集合 List<Filter> rowFilters 的組合結(jié)果,可選值:

MUST_PASS_ALL // 當(dāng)所有過(guò)濾器都允許包含這個(gè)值時(shí),才會(huì)加入到結(jié)果中
MUST_PASS_ONE // 只需要有一個(gè)過(guò)濾器允許包含這個(gè)值時(shí),就會(huì)加入到結(jié)果中

代碼示例:

Filter filter1 = new ...; 
Filter filter2 = new ...; 
Filter filter3 = new ...; 

FilterList filterList = new FilterList(Arrays.asList(filter1, filter2, filter3)); 

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

References:
《HBase 權(quán)威指南》

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 目錄: 引言 -- 參數(shù)基礎(chǔ) 1. 結(jié)構(gòu)(Structural)過(guò)濾器--FilterList 2.列值過(guò)濾器--...
    磊寶萬(wàn)歲閱讀 1,635評(píng)論 0 2
  • 一、簡(jiǎn)介 Hbase:全名Hadoop DataBase,是一種開(kāi)源的,可伸縮的,嚴(yán)格一致性(并非最終一致性)的分...
    菜鳥小玄閱讀 2,589評(píng)論 0 12
  • 簡(jiǎn)介 HBase是高可靠性,高性能,面向列,可伸縮的分布式存儲(chǔ)系統(tǒng),利用HBase技術(shù)可在廉價(jià)PC Serve...
    九世的貓閱讀 2,370評(píng)論 1 6
  • 首先,為啥要有過(guò)濾器呢? 我們都使用過(guò)get()和scan()來(lái)獲取HBase表中的數(shù)據(jù),不過(guò)我們?cè)谑褂眠^(guò)程中會(huì)發(fā)...
    MasterXiao閱讀 1,621評(píng)論 0 2
  • 基于列過(guò)濾的過(guò)濾器 1,ColumnPaginationFilter列分頁(yè)過(guò)濾器:基于列進(jìn)行分頁(yè),需要設(shè)置偏移量與...
    Coffeelong閱讀 5,466評(píng)論 0 7

友情鏈接更多精彩內(nèi)容