引言 -- 參數基礎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))
);
}
}